Possible Bug: BoundingBox for prims with geometries with skeleton animation are to large

Hello,

when we compute the bounding box of prims that contains one or more geometries with skeleton animations, those bounding boxes are to large in some cases.

Here you can see the min-Y value of the bounding box of such a prim:

As result the bounding box from the root tells me, that the root element “stands on the floor”, because ist min-y-value is zero… but as you can see, it does not “stand on the floor”… it levitating :-)

After deleting the skeleton, the bounding box is correct…

When creating images, we use the built in function “frameToPrims”. As you can see here the method has the same problem, because the calculated bounding box is much to large

Here is the geometry to reproduce this behavior…
ig_gfx_Candy_Twister_SeatCushion_SR80_LAR_geo_deformation_glb.zip (199.0 KB)

Thank you very much for your help

Carl

Here is a screenshot from USD compose, showing the problem… the calculated bounding box, is much to large…

And here is the original glb, that was imported

Candy.Twister.SeatCushion_SR80_LAR.zip (136.8 KB)

@eliabntt94 could this be the same problem as in your post [BUG] Bounding boxes 3d are not updated for animated meshes - Omniverse / Isaac Sim - NVIDIA Developer Forums?

Have you ever found a solution to this?

Thank you very much for your help

Carl

Hi, I used the trimesh package.
In short I query omniverse to get the vertices of my mesh, and use trimesh to get the 3D bbox.
The relevant code is here.

Your problem may be either that, or that you are querying the “wrong” prim/have put the object label to the “wrong” prim.

Hi,

thanks for your response. I’ve seen you solution, but I’ve two problems with that…

  1. It does only work on a mesh (to get the points), and I have to calculate the BB on a higher level of the scene graph… but OK, I could write a recursive BB calculation by myself…

  2. The bigger problem is, that I have to know the BB for a defined point in time and regardless of what I’ve tried so far, the points are always the same…

Carl

I don’t understand point 1. Sorry. The bbox should be of the mesh, and that’s the only way you can actually access the points necessary to compute the bbox. If you don’t have access to the vertices of the mesh, I don’t see how it is possible to compute a bbox.

For 2, you can simply use the code I shared and compute that at every time step accessing the mesh vertices at every iteration. Indeed I use points.ComputePointsAtTime(i, Usd.TimeCode(i)) which computes the vertices for a defined timestep. However, I think you still need the mesh itself.

Sorry for the unspecific description…

What I mean is… I have a scene graph of man nodes (with several transforms). And one of those subnodes has a geometry with deformations. I have to calculate the bb of the top node. But if I have to calculate the bb of geometries with deformation the way you described, I cannot use the usd methods to calculate the bb of the root… I hope that was a little bit mor accurate.

The second problem is, that I can of course only get the points from a mesh, and if I do that the way you describe, I always get the same points… regardeless of time value I use to calculate the points (as if the geometry wouldn’t have a deformation)

why can’t you query the geometry with deformation?

is the simulation playing when you query?

Sorry, I’m relatively new to 3D… so you mean… calculate the bbs of alle meshes they way you described in your post, and then appliy the world-transform of the root node to those bbs?

This is what I mean, when I said, that I always get the same points regardless of the timecode…

Shouldn’t those points be different?

This is the scene graph from the imported glb…
kit_mO5mSvqkvr

Ok, but is the animation happening between 1 and 50? I have not many ideas. Have you tried querying the mesh properties? There should be a “vertices” or “points” attribute. The problem seem similar IDK why the results are different. Unfortunately I cannot check in the next few days my computers are running training models and I’m on a deadline.

Thank you very much for your help 🙏

In the meantime I made some progress… I saved the geometry as usda and had a look at its content.

Them mesh had and extent attribute with its extend values. Those extent values where based on the mesh without any animation applied. The problem here is, that the animation deforms the geometry at start (time = 0), so the extent values did not match the default state of the geometry. But bedside of that, the values where correct (don’t know why the bounding box is calculated that large)…

Anyway I deleted the extent attribute and the misplacement got way better… but it is still wrong, because the bounding box calculation does not apply the animation, so the bounding box is always calculated based on the unanimated state of the geometry.

I read the usd doc about extent attributes etc. and I would like to calculate the extent for every time frame… but again I always get the same values regardless of the timecode… ComputePointsAtTime on the mesh returns always the same values too… totally lost… :-)

Here is an even more reduces sample…

Asset (this time with removed extent attribute):
Candy.Twister.SeatCushion_SR80_LAR (2).zip (199.0 KB)

When you open that usd in Compose you can run the animation… it does what it should do… so far so good.

So ComputeLocalBound for different TimeCodes should give different values - right:

from pxr import Usd, UsdGeom
import omni.usd

stage = omni.usd.get_context().get_stage()

prim = stage.GetPrimAtPath(“/RootNode”)
boundable = UsdGeom.Boundable(prim)

print(boundable.ComputeLocalBound(0, “default”))
print(boundable.ComputeLocalBound(10, “default”))
print(boundable.ComputeLocalBound(20, “default”))
print(boundable.ComputeLocalBound(30, “default”))
print(boundable.ComputeLocalBound(40, “default”))
print(boundable.ComputeLocalBound(50, “default”))
print(boundable.ComputeLocalBound(60, “default”))
print(boundable.ComputeLocalBound(70, “default”))
print(boundable.ComputeLocalBound(80, “default”))


As you can see here: It does not… even more wired (at least to me) is the fact that those values are total nonsense, because min-y and max-y are nearly the same value… and the geometry is clearly not a flat plane :-)

When using “/RootNode/Bone0120/SeatCushion_SR80_LAR” instead of “/RootNode” the values look like thats the bounding box for the unanimated mesh…

Can’t believe that it is so hard to calculate a bounding box in a tool like Omniverse :-)

@mati-nvidia could you do me a favor and have a look at this? This problem is a real show stopper for us… our first real customer that would like to use our Omniverse integration heavily relies on those deformation assets… thank you very much

Now I’ve read the whole documentation about skeletons etc. and I’m more confused than before now :-)

At first I’ve tested the sample from the usd documentation “Skinning an Arm” ( Universal Scene Description: Schema Intro By Example (openusd.org) ).

That works fine…

When using this script…

from pxr import Usd, UsdGeom
import omni.usd

stage = omni.usd.get_context().get_stage()

prim = stage.GetPrimAtPath(“/Model”)
boundable = UsdGeom.Boundable(prim)

print(boundable.ComputeLocalBound(0, “default”))
print(boundable.ComputeLocalBound(10, “default”))
print(boundable.ComputeLocalBound(20, “default”))
print(boundable.ComputeLocalBound(30, “default”))
print(boundable.ComputeLocalBound(40, “default”))
print(boundable.ComputeLocalBound(50, “default”))
print(boundable.ComputeLocalBound(60, “default”))
print(boundable.ComputeLocalBound(70, “default”))
print(boundable.ComputeLocalBound(80, “default”))

…the result is exactly what one would expect… 10 different bound for 10 different times:
kit_ycvsq0Zqq9

Then I’ve changed my geometry as far as possible to match that arm sample… I even have rounded values to get rid of exponential format (I had several problems in the past with that)… I even renamed the prims and bones to match the sample. But with no luck…

Executing the exakt same script on my geometry, results in this:

…ten times the same bounds and event that bound is wrong (y- and z- values of min and max are nearly identical).

Here are my usda-files:
UsdA-Samples.zip (62.5 KB)

What am I not seeing here? What is the problem… can anybody help?

Thanks

Carl

Hey @c.bickmeier. We can continue this on the AOUSD forum since it does seem like it could be a vanilla USD issue: Wrong bounding boxes for meshes with skeleton animation - USD - Alliance for OpenUSD