Rep.create.group not working

Hi, I have two folder paths: one for “dolls” and one for “hose”. I need to instantiate the two groups seperatly in order to assign semantics but then I need to group them together in order to proparly scatter all objects on the same plane. This is my code:

import omni.replicator.core as rep

HOSE_ON_GROUND_ASSETS_DIR = "C:/Users/dsiss/Desktop/Synthia-LFS/Omniverse/randomization_assets/water_hose/rolled_on_ground"
DOLLS_ASSETS_DIR = "C:/Users/dsiss/Desktop/Synthia-LFS/Omniverse/randomization_assets/toys/dolls"

plane_path = "/World/Plane"


with rep.new_layer():

	traversable_plane = rep.get.prim_at_path(plane_path)
	
	hoses_usd = rep.utils.get_usd_files(HOSE_ON_GROUND_ASSETS_DIR)
	hoses_prims = rep.randomizer.instantiate(hoses_usd, size=5, use_cache = False)
	with rep.utils.sequential():
	    with hoses_prims:
	        rep.modify.semantics(semantics = [("class", "hose")])
	
	dolls_usd = rep.utils.get_usd_files(DOLLS_ASSETS_DIR)
	dolls_prims = rep.randomizer.instantiate(dolls_usd, size=5, use_cache = False)
	with rep.utils.sequential():
	    with dolls_prims:
	        rep.modify.semantics(semantics = [("class", "toy")])
	
	group = rep.create.group(semantics=[("class", "hose"), ("class", "toy")])
	
	with rep.utils.sequential():
		with group:
			rep.randomizer.scatter_2d(traversable_plane, check_for_collisions=True)

the line

group = rep.create.group(semantics=[("class", "hose"), ("class", "toy")])

does not work.
get.prims does not work eaither.

How can I group these prims after instantiating (or before) while still assigning different semantics?

Thank you

Hi there,

the semantics argument will apply the given semantics to the items to be grouped:

cones = [rep.create.cone() for _ in range(100)]
group = rep.create.group(cones, semantics=[("class", "cone")])

you could use rep.get.prims for this:

cubes = rep.get.prims(semantics=[("class", "cube")])

Best,

Change it to

group = rep.create.group([hoses_prims, dolls_prims])

I believe what is happening in your original script is that rep.modify.semantics and rep.create.group are essentially evaluated at the same time (since there is no clear dependency on other objects in the code). So when rep.create.group is being evaluated, there are no prims with semantics=[("class", "hose"), ("class", "toy")].

By writing it as group = rep.create.group([hoses_prims, dolls_prims])

  1. You are using the exact prims you instantiated earlier
  2. By using variables from earlier in the script, a dependency is created and those are evaluated first

@dennis.lynch Hi, I tried this too but it does not work.

So this is my code:

import omni.replicator.core as rep

plane_path = "/World/Plane"
HOSE_ON_GROUND_ASSETS_DIR = "C:/Users/dsiss/Desktop/synthia-LFS/Omniverse/randomization_assets/water_hose/rolled_on_ground"
DOLLS_ASSETS_DIR = "C:/Users/dsiss/Desktop/synthia-LFS/Omniverse/randomization_assets/toys/dolls"



with rep.new_layer():

    traversable_plane = rep.get.prim_at_path(plane_path)

    hoses_usd = rep.utils.get_usd_files(HOSE_ON_GROUND_ASSETS_DIR)
    hoses_prims = rep.randomizer.instantiate(hoses_usd, size=4, with_replacements = False, use_cache = False)
    with rep.utils.sequential():
        with hoses_prims:
            rep.modify.semantics(semantics = [("class", "hose")])

    dolls_usd = rep.utils.get_usd_files(DOLLS_ASSETS_DIR)
    dolls_prims = rep.randomizer.instantiate(dolls_usd, size=4, with_replacements = False, use_cache = False)
    with rep.utils.sequential():
        with dolls_prims:
            rep.modify.semantics(semantics = [("class", "toy")])

    group = rep.create.group(items=[hoses_prims, dolls_prims])

    with rep.utils.sequential():
        with group:
            rep.randomizer.scatter_2d(traversable_plane, check_for_collisions=True)

But it seems that only the hose prims are properly scattered, meaning that the group only consists of hoses_prims. If i switch the order of the items list:

group = rep.create.group(items=[dolls_prims, hoses_prims])

Then same is still true, only the hose prims are scattered.

Hello again,

So I’ve verified a bug where scatter_2d does not work with prims created with instantiate

However, there seems to be a workaround by replacing instantiate with create.from_usd

My simple test code:

import omni.replicator.core as rep
# IsaacSim default is "Z", Code is "Y"
rep.settings.set_stage_up_axis("Z")
rep.settings.set_stage_meters_per_unit(0.01)

SURFACE = (
    "omniverse://localhost/NVIDIA/Assets/Scenes/Templates/Basic/display_riser.usd"
)
ENVS = "omniverse://localhost/NVIDIA/Assets/Scenes/Templates/Interior/ZetCG_ExhibitionHall.usd"
FRUIT_PROPS = {
    "apple": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Fruit/Apple.usd",
    "avocado": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Fruit/Avocado01.usd",
    "kiwi": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Fruit/Kiwi01.usd",
    "lime": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Fruit/Lime01.usd",
    "lychee": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Fruit/Lychee01.usd",
    "pomegranate": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Fruit/Pomegranate01.usd",
    "onion": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Vegetables/RedOnion.usd",
    "strawberry": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Food/Berries/strawberry.usd",
    "lemon": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Decor/Tchotchkes/Lemon_01.usd",
    "orange": "omniverse://localhost/NVIDIA/Assets/ArchVis/Residential/Decor/Tchotchkes/Orange_01.usd",
}
FRUIT_USD_LIST = list(FRUIT_PROPS.values())


with rep.new_layer():

    surface = rep.create.disk(scale=(5,5,5))
    apples = rep.create.from_usd(FRUIT_USD_LIST[0], count=10)
    oranges = rep.create.from_usd(FRUIT_USD_LIST[-1], count=10)

    fruit_group = rep.create.group(items=[apples, oranges])

    with rep.trigger.on_frame(max_execs=10):
        with fruit_group:
            rep.randomizer.scatter_2d(surface, check_for_collisions=False)
    

Modifying your code

import omni.replicator.core as rep

plane_path = "/World/Plane"
HOSE_ON_GROUND_ASSETS_DIR = "C:/Users/dsiss/Desktop/synthia-LFS/Omniverse/randomization_assets/water_hose/rolled_on_ground"
DOLLS_ASSETS_DIR = "C:/Users/dsiss/Desktop/synthia-LFS/Omniverse/randomization_assets/toys/dolls"


with rep.new_layer():

    traversable_plane = rep.get.prim_at_path(plane_path)

    hoses_usd = rep.utils.get_usd_files(HOSE_ON_GROUND_ASSETS_DIR)
    hoses_prims = rep.create.from_usd(hoses_usd, count=4, semantics=[("class", "hose")])

    dolls_usd = rep.utils.get_usd_files(DOLLS_ASSETS_DIR)
    dolls_prims = rep.create.from_usd(dolls_usd, count=4, semantics=[("class", "toy")])

    group = rep.create.group(items=[hoses_prims, dolls_prims])

    with rep.utils.sequential():
        with group:
            rep.randomizer.scatter_2d(traversable_plane, check_for_collisions=True)

You might need to change this a bit to match some of the “random selection” of instantiate by using distribution.choice on the prim paths

@dennis.lynch Thank you for this work around but it wont work since create.from_usd expects a path to a single usd but my path is a path to a directory.

I tried using choice:

with rep.new_layer():

    traversable_plane = rep.get.prim_at_path(plane_path)

    hoses_usds = rep.utils.get_usd_files(HOSE_ON_GROUND_ASSETS_DIR)

    hose = rep.distribution.choice(hoses_usds)

    with hose:
        rep.create.from_usd(semantics=[("class", "hose")])

But this does not work either. Using create.from_dir is also not an option as it selects all the usds in that directory.

@dennis.lynch

this does not work either:

with rep.new_layer():

    traversable_plane = rep.get.prim_at_path(plane_path)

    hoses_usds = rep.utils.get_usd_files(HOSE_ON_GROUND_ASSETS_DIR)

    hose = rep.distribution.choice(hoses_usds)

    rep.create.from_usd(hose, semantics=[("class", "hose")])

any idea why?

this code works (i can segment the different prims and scatter them). But I need to randomly select files from the directory (and not all the usd files)

    hose_prims = rep.create.from_dir(HOSE_ON_GROUND_ASSETS_DIR, recursive = True, semantics=[("class", "hose")])
    traversable_plane = rep.get.prim_at_path(plane_path)
    robot = rep.get.prim_at_path(robot_path)

    dolls_prims = rep.create.from_dir(DOLLS_ASSETS_DIR, recursive = True, semantics=[("class", "doll")])

    group = rep.create.group([hose_prims, dolls_prims])

    with group:
        rep.randomizer.scatter_2d(traversable_plane, no_coll_prims= [robot], check_for_collisions=True)
        rep.physics.collider()
        rep.modify.pose(rotation =rep.distribution.uniform((0,0,0), (0,0,180)))

You would do something like this to create multiple USD prims from a directory path and place them into a group object:

usds = rep.utils.get_usd_files(DIRECTORY_PATH)
object_list = []
for usd in usds:
    obj = rep.create.from_usd(usd), semantics=[("class", "thing")])
    object_list.append(obj)
 
object_group = rep.create.group(object_list) 

To do a random selection from the directory:

import random

usds = rep.utils.get_usd_files(DIRECTORY_PATH)
object_list = []
for usd in usds:
    obj = rep.create.from_usd(random.choice(usd)), semantics=[("class", "thing")])
    object_list.append(obj)
 
object_group = rep.create.group(object_list)