Compute the corners for an array of prims not a prim in Omniverse Code Script Editor

I wrote the following code which computes the corners for a single prim.

How can I pass an array of prims to it and compute the corners? I need to do this in Omniverse Code Script Editor not Isaac Sim.

import omni.usd

import omni.replicator.core as rep
from pxr import Usd, UsdGeom, Gf


#from omni.isaac.core.utils.stage import get_current_stage, open_stage

# import omni.isaac.core.utils.bounds as bounds_utils

# import omni.isaac.core.utils.prims as prims_utils

import numpy as np

ENV_URL ="omniverse://localhost/NVIDIA/Assets/Isaac/2022.2.0/Isaac/Samples/Replicator/Stage/full_warehouse_worker_and_anim_cameras.usd"

#open_stage(ENV_URL)
#result, error = omni.usd.get_context().open_stage(ENV_URL, load_set=omni.usd.UsdContextInitialLoadSet.LOAD_NONE)
omni.usd.get_context().open_stage(ENV_URL)

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

#floor_prims = [x.GetPath() for x in stage.Traverse() if "SM_floor" in x.GetName() and prims_utils.get_prim_type_name(x.GetPath()) == "Xform"]
floor_prims_paths = [x.GetPath() for x in stage.Traverse() if "SM_floor" in x.GetName() ]
print(floor_prims_paths)

print('dir floor_prims: ', dir(floor_prims_paths))
print('type(floor_prims[0]): ', type(floor_prims_paths[0]))

floor_prims = []
for floor_prim_path in floor_prims_paths:
    floor_prims.append(omni.usd.get_prim_at_path(floor_prim_path))

#bb_cache = bounds_utils.create_bbox_cache()

#combined_range_arr = bounds_utils.compute_combined_aabb(bb_cache, prim_paths=floor_prims)

#min_x, min_y, min_z, max_x, max_y, max_z = combined_range_arr

# bbox = omni.usd.get_context().compute_path_world_bounding_box(floor_prims[0])
# min_x, min_y, min_z, max_x, max_y, max_z = bbox

# print("bbox is: ", bbox)


def compute_bbox_with_cache(cache: UsdGeom.BBoxCache, prim: Usd.Prim) -> Gf.Range3d:
    """
    Compute Bounding Box using ComputeWorldBound at UsdGeom.BBoxCache. More efficient if used multiple times.
    See https://graphics.pixar.com/usd/dev/api/class_usd_geom_b_box_cache.html

    Args:
        cache: A cached, i.e. `UsdGeom.BBoxCache(Usd.TimeCode.Default(), ['default', 'render'])`
        prim: A prim to compute the bounding box.
    Returns:
        A range (i.e. bounding box), see more at: https://graphics.pixar.com/usd/release/api/class_gf_range3d.html

    """
    bound = cache.ComputeWorldBound(prim)
    bound_range = bound.ComputeAlignedBox()
    return bound_range
print('floor_prims: ', floor_prims)
print(type(floor_prims[0]))

bbcache = UsdGeom.BBoxCache(Usd.TimeCode.Default(), ["default", "render"])
print('bbache is: ', bbcache)
bb = compute_bbox_with_cache(bbcache, floor_prims[0])
print(bb)
print(type(bb))
print(bb.GetMax())
print(bb.GetMin())
print(dir(bb))
print(bb.GetCorner)

Also could you please verify if the way I have setup bbcash is correct? I am new to USD API.

Hi @mona.jalal

Did you find any solution for your query?

Hello, here’s an example of how to combine bounding boxes for multiple prims

import omni.usd as usd

def get_prim_bbox(prim, bboxcache=None):
    if bboxcache is None:
        purposes = [usd.UsdGeom.Tokens.default_]
        bboxcache = usd.UsdGeom.BBoxCache(usd.Usd.TimeCode.Default(), purposes)
    bbox = bboxcache.ComputeWorldBound(prim).ComputeAlignedRange()
    if bbox.IsEmpty():
        for child in usd.Usd.PrimRange(prim):
            if child.IsA(usd.UsdGeom.Boundable):
                sub_bound = bboxcache.ComputeWorldBound(child).ComputeAlignedRange()
                bbox.UnionWith(sub_bound)
    return bbox


def combine_prim_bboxes(prim_list):
    big_bbox = None
    for item in prim_list:
        item_bbox = get_prim_bbox(item)
        if big_bbox is None:
            big_bbox = item_bbox
        else:
            big_bbox.UnionWith(item_bbox)
    return big_bbox

It is also possible to put the multiple prims under the same xform parent and retrieve the bounding box from that object.