PixarAnimationStudios / OpenUSD

Universal Scene Description
http://www.openusd.org
Other
5.99k stars 1.18k forks source link

Document the prim hierarchy for "kind" metadata #1821

Closed spitzak closed 2 years ago

spitzak commented 2 years ago

Description of Issue

In the current overview and other documentation there is a diagram of the class inheritance of "kind", which is rather confusing to any user because it has nothing to do with what they are probably interested in: the prim hierarchy and how "kind" is assigned to various prims.

I wrote an example of the desired documentation (though please check for correctness!):

How prim "kind" metadata should be arranged, from parent prim down to child (please correct if wrong!):

/ Assembly (optional) Group (repeat 0-n times) Component (exactly 1) Subcomponent (repeat 0-n times)

Arbitrary numbers of XForm and typeless prims can be inserted between these, and any number of prims without any "kind" can be put below the last one.

spitzak commented 2 years ago

There is some documentation here, though it is still lacking a clear diagram of the arrangement the kind prims can have: https://graphics.pixar.com/usd/release/glossary.html#usdglossary-modelhierarchy

This appears to contradict with my above suggestion. It appears that non-kind prims are not allowed between the kind prims (or between the root and the top-most kind prim). In addition there can be 0-n Assembly prims. It still sounds a lot like there must be exactly one Component prim in a leaf path. New diagram:

Root (has no "kind" metadata) Assembly (repeat 0-n times) Group (repeat 0-n times) Component (exactly 1) Subcomponent (repeat 0-n times) arbitrary prims with no "kind"

spiffmon commented 2 years ago

"Root" must have a model kind, otherwise the model hierarchy would be broken. We typically make it a group, I believe.

At Pixar, subcomponents are not required to be a contiguous extension of the model hierarchy, so we might have:

Building   (kind=component)
  Geom
     FirstFloor
        ConfRoom1
            DoorAssembly
                Door (kind=subcomponent)
                    Knob (kind=subcomponent)

Door and Knob are subcomponents because they have transforms that may need to be animated, but none of the intervening ancestral prims may be interesting, and would just be "unrolled" as native prims in Maya/Presto.

Curious to hear @chrisrydalch thoughts on this.

@spitzak , stepping up a level, now that we're back in the thick of this, I think what we'd prefer is to beef up the "Model Hierarchy" entry you mentioned, and just provide a link as example to it from the libKind doxygen. Kind is much lower level than prims or scenegraphs, so from a (admittedly wonky) software layering perspective, kind should not be prescribing or discussing scenegraph organization - it's just a typing system.

spitzak commented 2 years ago

If the root is a "Group" then it sounds like Group and Assembly can be mixed in any order (ie Group or Assembly, 0-n times), is this correct?

It also sounds like no-kind prims can be inserted between some levels, but not others. Above says they can be put between Component and Subcomponent. Can they be put in other places? How about between the instances of the ones that can repeat?

The main change is because the metadata is called "kind", that is the section of the documentation people are going to go to. The word "model" does not appear. The section on "kind" should describe the prim hierarchy, by merging the "Model Hierarchy" and "Kind" sections. I would remove, or push to the bottom, the description of the kind class hierarchy, as it probably is of no interest to most users.

unhyperbolic commented 2 years ago

I just did an example on paper and I figured it might be instructive to share it here - or expose that I still don't understand it:

Kind hierarchy:

subcomponent
model
    component
    group
        assembly

Example prim hierarchy:

House_A (kind = component)
City_A (kind = group)
    Block_A (kind = group) [1] [2]
        House_B (kind = component) [3]
            Floor
                Door (kind = subcomponent) [4]
                    Knob (kind = subcomponent)
        Street_A (kind = assembly) [5]
            TrafficLight (kind = component)
                RedLight (kind = subcomponent)

[1] Prim is of kind group which is a subkind of model, thus its parent (if it exists) must be of kind group (or subkind of group, e.g., assembly). [2] All children of a prim of kind group (or subkind of group) must have a kind. [3] Like [1], Prim is a subkind of model, thus its parent must be of kind group. [4] Prim if of kind subcomponent and thus must have some ancestor of kind component. [5] assembly is a subkind of group, so [1] and [2] apply.

spitzak commented 2 years ago

If that example is correct, then perhaps I have it backwards, and "Group" is above "Assembly":

Root (kind=Group)
 Group (repeat 0-n times)
   Assembly (repeat 0-n times)
     Component (exactly 1)
       type-less prims (0-n times)
         Subcomponent (repeat 0-n times)
           type-less prims (0-n times)
unhyperbolic commented 2 years ago

@spitzak I think you are right - though the glossary language about group and assembly is "generally" and "tend", so I think what I have is consistent with USD's definition of a valid model hierarchy but not recommended.

spiffmon commented 2 years ago

@spitzak , you are implying a prefixing semantic that isn't there. As you said earlier, the leaf node of every model hierarchy is a component. But its ancestors can be a free mix of assembly, group, or any other group-derived kind.

spitzak commented 2 years ago

Is this correct then:

For any (correct) prim path, there is at most one Component.

Above the Component there can only be Group and Assembly, any number of them (including zero) in any order. Below the Component there can only be Subcomponent, any number of them (including zero).

If there is no Component then the path can have Group and Assembly in it, but no Subcomponents.

Prims without a "kind" can be inserted between prims with a "kind" anywhere in the path.

unhyperbolic commented 2 years ago

@spitzak I think your last statement is wrong - that is there is "namespace contiguity" for the model hierarchy and you cannot have a prim without a kind between any two prims that are of a subkind of "model" - including that you cannot have a prim without kind between the pseudoroot and a prim of a subkind of "model". In particular, a prim without a kind cannot be a parent of a "group" or "assembly". Ancestors of a "component" can be without kind. In other words, components are leaf nodes of the model hierarchy (well, technically speaking a "group" could also be a leaf node of the model hierarchy but it couldn't have any namespace children whatsoever).

spiffmon commented 2 years ago

@unhyperbolic , I think your second-to-last sentence was meant to be: Descendants of a "component" can be without kind.

The only other thing we should consider, because we have had structures in the sets department before that violate it, is whether group prims can only have model-prim children. I am unsure whether the "embedded reference model" construct fully obviated the need they had. Possibly @mrawde knows...

unhyperbolic commented 2 years ago

@unhyperbolic , I think your second-to-last sentence was meant to be: Descendants of a "component" can be without kind.

Yes.

The only other thing we should consider, because we have had structures in the sets department before that violate it, is whether group prims can only have model-prim children.

I think that without model contiguity, we loose the following property: To validate a model hierarchy, it is sufficient to check for each prim a predicate that only depends on the kind of the prim and kind of its namespace parent.