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

usdGeom: add validation for gprim parenting #3212

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from

Conversation

beersandrew
Copy link
Contributor

Description of Change(s)

  • added a validation rule that reports an error on a boundable prim that has a gprim ancestor

Fixes Issue(s)

  • I have verified that all unit tests pass with the proposed changes
  • I have submitted a signed Contributor License Agreement

UsdValidationErrorSite(usdPrim.GetStage(),
usdPrim.GetPath())
},
TfStringPrintf("Gprim <%s> has an ancestor prim that is also a Gprim,"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be Boundable <%s> has an ancestor prim that is a Gprim?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, updated

@nvmkuruc
Copy link
Collaborator

nvmkuruc commented Aug 8, 2024

Spiff's comment here suggests that Xformables should also be discouraged.
https://forum.aousd.org/t/clarity-on-nesting-imageables-under-gprims/1603

@marktucker
Copy link
Contributor

I wonder if it would make more sense (and be simpler and faster to run) if we flip this check around and make it so that gprims look at their children/descendants, and raise an error if there is anything under them besides a UsdGeomSubset? Are there other valid descendants for gprims in standard USD? Or would this implementation be too limiting in terms of custom prim types that someone might want to place under gprims? Having written this all down I'm leaning towards leaving the test as-is, but it seems to me like it's worth at least considering.

@nvmkuruc
Copy link
Collaborator

nvmkuruc commented Aug 8, 2024

I had the same thought @marktucker 👍

I could see an argument in wanting something like Scope to be used for organizing GeomSubsets. But I don't have a strong opinion as to whether or not that should be allowed and arguably the subset properties could be used to organize subsets for user presentation.

# Example of using intermediate scopes to organize subsets
def Mesh "mesh"
{
   def Scope "MaterialSubsets" {
       def GeomSubset "subset_1" { ... }
   }
   def Scope "PhysicsSubsets" {
       def GeomSubset "subset_1" { ... }
    }
}

@beersandrew
Copy link
Contributor Author

Spiff's comment here suggests that Xformables should also be discouraged. https://forum.aousd.org/t/clarity-on-nesting-imageables-under-gprims/1603

I've included Xformable in the check for now, however following your discussion with @marktucker I also thought to check the Gprims themselves.

I'm not sure what the technical impact or implications of wrapping the Geomsubsets in Scope prims are, but it seems like a reasonable thing to want to do from an organizational standpoint. Would it make sense in that case that a Scope with a Gprim ancestor is valid if and only if it has a Geomsubset descendant?

@marktucker
Copy link
Contributor

Putting GeomSubsets inside scopes is a nice idea. I hope Hydra accepts it... If that organization is acceptable, now we've gone from one "acceptable" descendant type to two, and I think the rule should be left as is. However if GeomSubsets in scopes doesn't work in Hydra, then that would be an argument for checking descendants instead of ancestors.

So I just tried this, and if the GeomSubsets are under a scope, the materials bound to them no longer show up. So I think this is unsupported, at least by Hydra currently, so maybe checking descendants is a good idea after all...

@nvmkuruc
Copy link
Collaborator

nvmkuruc commented Aug 8, 2024

@marktucker I think even if the acceptable type list increases, your suggestion of checking descendants will always be more efficient than checking ancestors.

@marktucker
Copy link
Contributor

Efficient, yes. But is it correct? My one remaining fear about it is that someone may add a "MyCustomGprimFeature" prim type which is intended to go under a gprim and a descendants check will flag it as an error because the validator doesn't know it's allowed to be there. But maybe this is an edge case not worth worrying about?

Or maybe we'd hit this kind of "exception" problem with the ancestor check (for example, the Scope prim under the gprim would not be flagged as problematic by the current ancestor check unless we start adding special cases as @beersandrew suggested above).

Okay, I'm now firmly on the side of "check descendants, not ancestors".

@jesschimein
Copy link
Contributor

Filed as internal issue #USD-9952

@jesschimein
Copy link
Contributor

/AzurePipelines run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@beersandrew
Copy link
Contributor Author

Okay, I'm now firmly on the side of "check descendants, not ancestors".

Updated this PR to go in that direction, let me know what you think

currentPrim.GetTypeName().GetText(),
validGprimDescendantTypeNames.c_str())
);
break;
Copy link
Contributor

Choose a reason for hiding this comment

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

_SubsetFamilies doesn't "break" when it finds an error - it keeps iterating and returns all errors. Maybe the same approach should be used here, pointing out all invalid descendant prims in one run, rather than just returning the first bad prim?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would like to stay consistent however in the case of having multiple skel properties on a prim that does not have the SkelBindingAPI applied, it was suggested to stop after the first one.

#3166 (comment)

Is there a determining factor for when to get all errors vs the first error? (multiple prim errors -> get all, multiple property errors -> get first?) or is it case by case and trying to stay consistent isn't necessary?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the context is different. In case of skel binding, the issue is with the non-application of SkelBindingAPI and presence of even a single property which belongs to SkelBindingAPI.

However, here we must report each descendant prim which is illegal within its scope.

Copy link
Contributor

Choose a reason for hiding this comment

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

@beersandrew looks like you forgot to take the break out here? Was there a reason for this? If not, lmk and I will update it internally, already synced the PR in. Thanks

@jesschimein
Copy link
Contributor

/AzurePipelines run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mattyjams
Copy link
Contributor

mattyjams commented Aug 12, 2024

Putting GeomSubsets inside scopes is a nice idea. I hope Hydra accepts it... If that organization is acceptable, now we've gone from one "acceptable" descendant type to two, and I think the rule should be left as is. However if GeomSubsets in scopes doesn't work in Hydra, then that would be an argument for checking descendants instead of ancestors.

So I just tried this, and if the GeomSubsets are under a scope, the materials bound to them no longer show up. So I think this is unsupported, at least by Hydra currently, so maybe checking descendants is a good idea after all...

Hey all! Sorry for chiming in late here, but I was recently rooting around in this code and added a bunch of the GeomSubset-related validators in #3123.

As @marktucker found, I don't expect any hierarchical structuring of GeomSubsets to work other than having them as direct descendants of the Imageable they are a subset of. The SubsetParentIsImageable validator tests for this (from GeomSubset prims):

_SubsetParentIsImageable(const UsdPrim& usdPrim)

The subset fetching functions all currently look only at immediate children when looking for subsets, so anything deeper in namespace would not be found, e.g.:

geom.GetPrim().GetFilteredChildren(_GetGeomSubsetPredicate())) {

Given that current restriction, it feels like the SubsetParentIsImageable validator and the GPrimDescendantValidator validator here are testing for almost the same thing? In the context of subsets, the difference would be that you could have a structure with a hierarchy of subsets (.../Imageable/GeomSubset/GeomSubset), and the former validator would complain that the "leaf" subset does not have an Imageable parent while the latter validator would not report any error. They are admittedly testing in different "directions" though, with SubsetParentIsImageable testing a GeomSubset's immediate ancestor, while GPrimDescendantValidator tests all descendants, so the latter would catch other problematic structures that the former would not. I guess I wonder whether there's some way to combine those two or otherwise make it more clear?

Supporting hierarchies of subsets under Imageables might indeed be useful, but it would at least need changes in those fetching functions, if not elsewhere, before they would work.

@beersandrew
Copy link
Contributor Author

Given that current restriction, it feels like the SubsetParentIsImageable validator and the GPrimDescendantValidator validator here are testing for almost the same thing?

The GPrimDescendantValidator can't have a validation error on a GeomSubset prim and the SubsetParentIsImageable validator can only have a validation error on the GeomSubset prim. Possibly that distinction isn't valuable and if the user runs all validators on all prims, they would get duplicate errors in the Mesh > Scope > GeomSubset hierarchy, once for the Mesh and once for the GeomSubset.

If it's assumed that by default users would run all of the validation rules, then I think it does make sense to specify which of the Mesh or GeomSubset should be invalid. Is there some historic precedent around this where the default blame goes to the parent or the child?

@jesschimein
Copy link
Contributor

/AzurePipelines run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@tallytalwar
Copy link
Contributor

Hey @beersandrew, there are some updated to the dev branch, which will require rebasing / updated here. Can you please do that, once done, I will sync this PR in. Thanks

- added a validation rule that reports an error on a boundable prim that has a gprim ancestor
- added more test criteria to make sure GeomSubsets are tested to be valid
@beersandrew beersandrew force-pushed the usdgeom-gprim-parenting-validator branch from 3b6aaaa to 30ce460 Compare September 9, 2024 22:16
- fixed an extra declaration of errors
- added ErrorNameToken for InvalidGPrimDescendent
@beersandrew
Copy link
Contributor Author

Hey @beersandrew, there are some updated to the dev branch, which will require rebasing / updated here. Can you please do that, once done, I will sync this PR in. Thanks

@tallytalwar This is updated on top of dev now. let me know if you see anything else that needs to be updated

- removing break allows for all errors to be collected
@jesschimein
Copy link
Contributor

/AzurePipelines run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants