In 8ba7b01 the instanceProxyPathTranslationSceneIndex was changed to follow breadcrumbs for nested instancing. While this seems to work well for nested native instancing, it can break when point instancing is included in the mix.
Let's say that after all the NI & PI SceneIndexes have run, there's a resulting hierarchy of: /a/b/c/d/e/f/g/mat. Further, the instance breadcrumbs on /a/b say that the replacement prototype is /a/b/c/d and the instance breadcrumbs on /a/b/c/d/e say that the replacement prototype is /a/b/c/d/e/f/g.
Now, if we have a material binding to /a/b/e/mat, the Scene Index works nicely:
- start with
/
- append
a - have /a - no breadcrumb, carry on
- append
b - have /a/b - breadcrumb found - replace work with /a/b/c/d
- append
e - have /a/b/c/d/e - breadcrumb found - replace work with /a/b/c/d/e/f/g
- append
mat - have /a/b/c/d/e/f/g/mat - success!
However ......... somewhere in the mix of PI & NI Scene Indexes, /a/b/e/mat is being "pre-expanded" to /a/b/c/d/e/mat. It's still not the final path, so the instanceProxyPathTranslationSceneIndex still intercepts it:
- start with
/
- append
a - have /a - no breadcrumb, carry on
- append
b - have /a/b - breadcrumb found - replace work with /a/b/c/d
- append
c - have /a/b/c/d/c - we've now gone off the rails, prim doesn't even exist, but loop continues
- append
d - have /a/b/c/d/c/d - still going, even though this prim doesn't even exist
- append
e - have /a/b/c/d/c/d/e - still going, even though this prim doesn't even exist
- append
mat - have /a/b/c/d/c/d/e/mat - we've reached the end of the path segments to append
Either we need to ensure there are no "pre-expanded" paths before this scene index runs, or we should work back-to-front, looking for the longest "relocation", not the shortest. In that scenario we'd do something like this:
- start with
/a/b/c/d/e/mat - not a prim, carry on
- strip back to
/a/b/c/d/e - breadcrumb, replace /a/b/c/d/e with /a/b/c/d/e/f/g in original path and restart loop
- start with
/a/b/c/d/e/f/g/mat - this is what we want - success!
To show it also works with the first working case:
- start with
/a/b/e/mat - not a prim, carry on
- strip back to
/a/b/e - not a prim, carry on
- strip back to
/a/b - breadcrumb, replace /a/b with /a/b/c/d in original path and restart loop
- start with
/a/b/c/d/e/mat - now we're in the case above which we showed works
PR will be sent shortly.
Example USD scene that demonstrates the issue ... sphere should be green but isn't.
#usda 1.0
(
startTimeCode = 1
endTimeCode = 1
framesPerSecond = 24
metersPerUnit = 1
timeCodesPerSecond = 24
upAxis = "Y"
)
over "materials_proto"
{
def Material "green"
{
token outputs:surface.connect = </materials_proto/green/usdpreviewsurface.outputs:surface>
def Shader "usdpreviewsurface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:emissiveColor = (0, 1, 0)
token outputs:surface
}
}
}
over "scene_proto"
{
def Sphere "sphere" (
apiSchemas = ["MaterialBindingAPI"]
)
{
rel material:binding = </scene_proto/materials/green>
}
def Scope "materials" (
instanceable = true
add references = </materials_proto>
)
{
}
}
def PointInstancer "pointinstancer"
{
point3f[] positions = [(0, 0, 0)]
int[] protoIndices = [0]
rel prototypes = </pointinstancer/Prototypes/scene>
def Scope "Prototypes" (
kind = "group"
)
{
def Xform "scene" (
instanceable = true
add references = </scene_proto>
)
{
}
}
}
In 8ba7b01 the instanceProxyPathTranslationSceneIndex was changed to follow breadcrumbs for nested instancing. While this seems to work well for nested native instancing, it can break when point instancing is included in the mix.
Let's say that after all the NI & PI SceneIndexes have run, there's a resulting hierarchy of:
/a/b/c/d/e/f/g/mat. Further, theinstancebreadcrumbs on/a/bsay that the replacement prototype is/a/b/c/dand theinstancebreadcrumbs on/a/b/c/d/esay that the replacement prototype is/a/b/c/d/e/f/g.Now, if we have a material binding to
/a/b/e/mat, the Scene Index works nicely:/a- have/a- no breadcrumb, carry onb- have/a/b- breadcrumb found - replace work with/a/b/c/de- have/a/b/c/d/e- breadcrumb found - replace work with/a/b/c/d/e/f/gmat- have/a/b/c/d/e/f/g/mat- success!However ......... somewhere in the mix of PI & NI Scene Indexes,
/a/b/e/matis being "pre-expanded" to/a/b/c/d/e/mat. It's still not the final path, so the instanceProxyPathTranslationSceneIndex still intercepts it:/a- have/a- no breadcrumb, carry onb- have/a/b- breadcrumb found - replace work with/a/b/c/dc- have/a/b/c/d/c- we've now gone off the rails, prim doesn't even exist, but loop continuesd- have/a/b/c/d/c/d- still going, even though this prim doesn't even existe- have/a/b/c/d/c/d/e- still going, even though this prim doesn't even existmat- have/a/b/c/d/c/d/e/mat- we've reached the end of the path segments to appendEither we need to ensure there are no "pre-expanded" paths before this scene index runs, or we should work back-to-front, looking for the longest "relocation", not the shortest. In that scenario we'd do something like this:
/a/b/c/d/e/mat- not a prim, carry on/a/b/c/d/e- breadcrumb, replace/a/b/c/d/ewith/a/b/c/d/e/f/gin original path and restart loop/a/b/c/d/e/f/g/mat- this is what we want - success!To show it also works with the first working case:
/a/b/e/mat- not a prim, carry on/a/b/e- not a prim, carry on/a/b- breadcrumb, replace/a/bwith/a/b/c/din original path and restart loop/a/b/c/d/e/mat- now we're in the case above which we showed worksPR will be sent shortly.
Example USD scene that demonstrates the issue ... sphere should be green but isn't.