Problems with pattern-based collections

Hi,

We’re investigating using pattern-based collections in 23.11 and have run into a number of issues. This Python code demonstrates the problems:

from pxr import Usd, Sdf

stage = Usd.Stage.CreateInMemory()
stage.DefinePrim('/apple')
stage.DefinePrim('/banana')
stage.DefinePrim('/pineapple')
stage.DefinePrim('/applepie')

collectionPrim = stage.DefinePrim('/collection')
collection = Usd.CollectionAPI.Apply(collectionPrim, 'test:collection')

def test_pattern(pattern):
  collection.CreateMembershipExpressionAttr().Set(Sdf.PathExpression(pattern))
  paths = [p.pathString for p in Usd.CollectionAPI.ComputeIncludedPaths(collection.ComputeMembershipQuery(), stage)]
  print(f'{pattern} matches {paths}')

test_pattern('/apple')
test_pattern('/banana')
test_pattern('/pineapple')
test_pattern('/apple*')
test_pattern('/appl?')
test_pattern('/ap?le')
test_pattern('/*apple')

This produces:

/apple matches ['/apple']
/banana matches []
/pineapple matches []
/apple* matches ['/apple', '/applepie', '/pineapple']
/appl? matches ['/apple', '/applepie', '/pineapple']
/ap?le matches ['/apple', '/applepie', '/pineapple']
/*apple matches ['/apple', '/applepie', '/pineapple']

First problem: Only the first defined prim can be matched when no wildcards are present. I can reorder the DefinePrim statements, and only the first one will ever match.

Second problem: Any sort of wildcard in a path element seems to work as iff the whole element was just a wildcard.

Am I doing something wrong here, or are these bugs? I was unable to find any issues filed on on this.

Jerry

Hey Jerry – I’m quite sure you’re missing some bugfixes on our end. This feature is still a bit “fresh”. Here’s what I get when I run your script on dev:

/apple matches ['/apple']
/banana matches ['/banana']
/pineapple matches ['/pineapple']
/apple* matches ['/apple', '/applepie']
/appl? matches ['/apple']
/ap?le matches ['/apple']
/*apple matches ['/apple', '/pineapple']

Which I think looks correct to me. If you’d like I can track down the relevant commits for you, let me know.

Thanks for the reply. This was with the 23.11 release. I’ll try with the dev branch and see what happens. A list of the commits for the fixes would be useful though.

Unfortunately, we’re moving our next release to base on USD 23.11, so this means we probably won’t be able to support pattern-based collections for a while. We were hoping to retire our home-grown pattern matcher which is a subset of the full pattern-based collection syntax. We’d prefer not to get into a state where we have to support it as well as PBCs if there are any inconsistencies between the two.

Jerry

Hi Jerry – I took a look at the commit history and there have been quite a lot of relevant changes since 23.11. I’m concerned that trying to cherry-pick all of them into a 23.11 branch might not be fruitful, pulling dependency threads and such.

FWIW, the 24.03 release (containing the fixes) is anticipated in the next few weeks, though I realize that may not be viable for you. Sorry for the trouble here.

Hi,

Thanks for researching this. I think you’re right. We won’t want to be patching USD, especially as we allow users to replace the USD we ship with their own. We’ll stick to our own pattern matcher for the moment, but make absolutely sure that we support a strict subset of the syntax and behaviour to avoid surprises later when we switch over.

Jerry

Hi everyone,
We’re hitting some problems using Pattern Based Collections in USD 24.05, can anyone spot what we might be doing wrong here? On a layer we define a collection foos which includes /root/foo1 and /root/foo2`:

def "root" (
    prepend apiSchemas = ["CollectionAPI:foos", "CollectionAPI:foos_pbc"]
) {
    rel collection:foos:includes = [</root/foo1>, </root/foo2>]
    uniform pathExpression collection:foos_pbc:membershipExpression = "%/root:foos"

    def Cone "foo1" {
    }
    def Sphere "foo2" {
    }
}

We also create a collection foos_pbc which references /foos.
I would expect foos2 to be the same as foos, but calling:

collection = Usd.CollectionAPI(root, "foos_pbc")
query = collection.ComputeMembershipQuery()
paths = Usd.ComputeIncludedPathsFromCollection(query, stage)

returns paths as empty. Can anyone spot something syntaxically wrong, are we using the wrong methods or is there potentially a bug somewhere in the PBC evaluation?
Thanks!

Hi alasdairhitchen! At the moment, you can’t use includes/excludes (“relationship-mode”) collections as sub-expressions in a pattern-based collection. In your example you’d have to convert foos to a path expression, e.g.

uniform pathExpression collection:foos:membershipExpression = "/root/foo*"

(or even “/root/foo1 + /root/foo2”) to reference it in foos_pbc.

There’s also a new method on CollectionMembershipQuery that computes an equivalent path expression from a rule map that should be available in the 24.08 release.