How to set the visibility of a prim to a specific camera (in a multiple camera case)?

Hi, I have a problem about prim visibility to cameras.
Simplify my problem to this case: there are 2 Cameras X, Y and 2 prims A, B in a scene. I want the camera X only render prim A and camera Y only render prim B. That is, wherever the camera X is, prim B will never appeared in its rendered image, the same for Y.
I know that it is easy for to set global visibility for prim A/B, which can solve the problem in a ugly way: InVisible(B) → Camera X shot → Visible(B) → InVisible(A) → Camera Y shot → Visible(A) …
For the real case, there are multiple cameras and each camera needs to focus on different collection of prims. I wonder if there is a simple way to make this, thanks.

Hi mulplue,

Maybe write a script can help you for this task:
dynamically disable prim with name rules.

==========sample code=========
code 1:
from pxr import Usd, UsdGeom

Load the stage with a given USD file

stage = Usd.Stage.Open(“path/to/your/file.usd”)

Define the rule for names you want to search for

def name_matches_rule(name):
# Here you can define your own logic
# For example, turn off all prims with “temp” in the name:
return “temp” in name

Iterate through all prims in the stage

for prim in stage.TraverseAll():
if name_matches_rule(prim.GetName()):
# Set the visibility attribute to “invisible”
UsdGeom.Imageable(prim).GetVisibilityAttr().Set(UsdGeom.Tokens.invisible)

Save changes

stage.GetRootLayer().Save()

code 2:

from omni.isaac.core.utils.prims import set_prim_visibility
set_prim_visibility(prim, False)

Hi Jeffli, thanks for your reply!
I’ve read your code, however, what I want is not globally set the visibility property. For Example, when I use your scipt to turn off prim “A”, both camera “X” and “Y” can’t see “A”.
The ideal situation is: camera “X” can only see prim “A”, and camera “Y” can only see prim “B”, at the same time&stage. This can’t be archieved by set global visibility(like set_prim_visibility(prim, False)).
A possible way may like this: set all prims visible, but change the renderVisibility property during rendering(I found this property in usd doc, but I didn’t find related functions in pxr.UsdRender). So that we can set different redering process for camera “X” and “Y” to make them see different prims at the same time. However, I don’t know how to make this in isaac sim.

Hi mulplue,
pxr usdgeom has such api,renderVisibility UsdGeom module — pxr-usd-api 105.1 documentation (nvidia.com),
if the given prim is a primitive geometry object prim, you may use this api

Hi Jeffli,
I have read the doc carefully, but I still don’t know how to apply the renderVisibility attribute to a specific camera. Are there any code examples? In my case, the code framework is like this(running in script editor):

import omni
import numpy as np
from pxr import Usd, UsdGeom
from omni.isaac.core.objects import DynamicCuboid

from omni.isaac.sensor import Camera
import omni.isaac.core.utils.numpy.rotations as rot_utils


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

# create cube a and b
path_a = "/World/cube_a"
path_b = "/World/cube_b"
cube_a = DynamicCuboid(
    prim_path=path_a,
    name="fancy_cube",
    position=np.array([2.0, 0, 0]),
    color=np.array([0, 0, 1.0]),
)
cube_b = DynamicCuboid(
    prim_path=path_b,
    name="fancy_cube",
    position=np.array([-2.0, 0, 0]),
    color=np.array([1, 0, 0]),
)

# create camera x and y
camera_x = Camera(
    prim_path="/World/camera_x",
    position=np.array([2.0, 0.0, 50.0]),
    frequency=20,
    resolution=(256, 256),
    orientation=rot_utils.euler_angles_to_quats(np.array([0, 90, 0]), degrees=True),
)
camera_y = Camera(
    prim_path="/World/camera_y",
    position=np.array([-2.0, 0.0, 50.0]),
    frequency=20,
    resolution=(256, 256),
    orientation=rot_utils.euler_angles_to_quats(np.array([0, 90, 0]), degrees=True),
)

# attach renderVisibilityAPI to cube a and b
render_vis_a = UsdGeom.VisibilityAPI.Apply(stage.GetPrimAtPath(path_a))
render_vis_b = UsdGeom.VisibilityAPI.Apply(stage.GetPrimAtPath(path_b))
render_vis_a.CreateRenderVisibilityAttr()
render_vis_b.CreateRenderVisibilityAttr()

# make cube_a only visible to camera_x
# TODO
# make cube_b only visible to camera_y
# TODO

I can’t get any reference to help me write the #TODO part, can you give me some supports? Thank very very much!

Hi mulplue,
Sorry for late response, not sure one camera can render related to a specific camera, let me check internally and sync up later.

Hi mulplue,
Check internally, render to specific prim is not supported.

1 Like

Thanks! Would Isaac Sim add this property in the recent future?