Scatter2d exclude other prims

Hi, I am facing the same issue in a previous post: Scatter_2d collisions with static objects - #21 by hclever
I am trying to use scatter2d separately on multiple objects imported from usd and am trying to scatter them in separate planes without colliding. May I know if there are any plans to include the volume_excl_prims option or something similar?
Thanks

Hi Frederick, let me make sure I understand: so you want to do something similar to the previous post, but rather than specifying a single plane you want to be able to specify multiple planes and multiple exclusion volumes? Do you have a specific number of either you need or do you want to be able to use N planes and M excl prims?

Also, can you confirm you are on replicator 1.7?

-Henry

Yes I am on replicator 1.7.7

I would like to with code like this:

with rep.new_layer():
    small_plane = rep.create.plane(scale=(10,1,10), visible=False)
    large_plane = rep.create.plane(scale=(20,1,10), visible=False)
    
    large_sphere = rep.create.sphere(semantics=[('class', 'sphere')], position=(0, 100, 100),count=2)
    small_cube = rep.create.cube(semantics=[('class', 'cube')], scale=(0.1), position=(0, 100, 100),count=20)
    
    def scatter_large():
        large=rep.get.prims(semantics=[("class", "sphere")])
        with large:
            rep.randomizer.scatter_2d(surface_prims=small_plane, check_for_collisions=True)
        return large.node
        
    def scatter_small():
        small=rep.get.prims(semantics=[("class", "cube")])
        with small:
            rep.randomizer.scatter_2d(surface_prims=large_plane, check_for_collisions=True)
        return small.node

generate smaller squares randomly within the larger plane such that it can spawn between the larger spheres without collision.

Hi,

I was able to do this using the replacement replicator files from the previous forum post - I attached it here. I used the following code in the script editor:

import omni.replicator.core as rep
import omni.usd

with rep.new_layer():
    small_plane = rep.create.plane(scale=(1.5,1,1.5), visible=True)
    large_plane = rep.create.plane(scale=(1.7,1,1.5), visible=True)
    
    large_sphere = rep.create.sphere(semantics=[('class', 'sphere')], position=(0, 100, 100),count=2)
    small_cube = rep.create.cube(semantics=[('class', 'cube')], scale=(0.1), position=(0, 100, 100),count=30)
    
    def scatter_large():
        large=rep.get.prims(semantics=[("class", "sphere")])
        with large:
            rep.randomizer.scatter_2d(surface_prims=small_plane, check_for_collisions=True)
        return large.node
        
    def scatter_small():
        small=rep.get.prims(semantics=[("class", "cube")])

        stage = omni.usd.get_context().get_stage()
        large_plane_path = "/Replicator/Plane_Xform_01/Plane"
        large_sphere_1 = "/Replicator/Sphere_Xform/Sphere"
        large_sphere_2 = "/Replicator/Sphere_Xform_01/Sphere"
        with small:
            rep.randomizer.scatter_2d(surface_prims=[large_plane_path, large_sphere_1, large_sphere_2], check_for_collisions=True)
        return small.node

    rep.randomizer.register(scatter_large)
    rep.randomizer.register(scatter_small)

    with rep.trigger.on_frame(num_frames=1):
        rep.randomizer.scatter_large()
        rep.randomizer.scatter_small()


rep.orchestrator.run()

It’s good to know there is more interest in this feature - I will try to get it into replicator soon.

-Henry



OgnScatter2D.py (17.3 KB)
utils.py (46.3 KB)

Hi, do you think there is any way i could get this working with an imported usd?

My sample code is here:

import omni.replicator.core as rep

with rep.new_layer():
    plane_s = rep.create.plane(scale=10, visible=False)
    plane_l = rep.create.plane(scale=20, visible=False)
    WORKER = 'omniverse://localhost/NVIDIA/Assets/Characters/Reallusion/Worker/Worker.usd'


    def place_sphere():
        spheres = rep.create.sphere(semantics=[('class', 'sphere')], position=(0, 100, 0), count=5)
        with spheres:
            rep.randomizer.scatter_2d(surface_prims=plane_s, check_for_collisions=True)
        return spheres.node

    # def place_cube():
    #     cubes = rep.get.prims(semantics=[('class', 'cube')])
    #     spheres = rep.get.prims(semantics=[('class', 'sphere')])
    #     with cubes:
    #         rep.randomizer.scatter_2d(surface_prims=[plane_l, spheres, cubes], check_for_collisions=True)
    #     return cubes.node

    def place_worker():
        spheres = rep.get.prims(semantics=[('class', 'sphere')])
        worker = rep.create.from_usd(WORKER, semantics=[('class', 'worker')], count=20)
        with worker:
            rep.randomizer.scatter_2d(surface_prims=[plane_l, spheres], check_for_collisions=True)
        return worker.node

    rep.randomizer.register(place_sphere)
    # rep.randomizer.register(place_cube)
    rep.randomizer.register(place_worker)

    with rep.trigger.on_frame(num_frames=5, rt_subframes=60):
        rep.randomizer.place_sphere()
        rep.randomizer.place_worker()

I think it should work … what is the current issue?

The workers do not get scattered and stay in their original position

Hmm. Can you try this:

        rep.create.from_usd(WORKER, semantics=[('class', 'worker')], count=20)
        workers = rep.get.prims(semantics=[('class', 'worker')])
        with workers:
            rep.randomizer.scatter_2d(surface_prims=[plane_l, spheres], check_for_collisions=True)

If that doesn’t work i’ll poke around tomorrow and see what I can do.

Nope still having the same issue with this code:

import omni.replicator.core as rep

with rep.new_layer():
    plane_s = rep.create.plane(scale=10, visible=False)
    plane_l = rep.create.plane(scale=20, visible=False)
    WORKER = 'omniverse://localhost/NVIDIA/Assets/Characters/Reallusion/Worker/Worker.usd'


    def place_sphere():
        spheres = rep.create.sphere(semantics=[('class', 'sphere')], position=(0, 100, 0), count=5)
        with spheres:
            rep.randomizer.scatter_2d(surface_prims=plane_s, check_for_collisions=True)
        return spheres.node

    # def place_cube():
    #     cubes = rep.get.prims(semantics=[('class', 'cube')])
    #     spheres = rep.get.prims(semantics=[('class', 'sphere')])
    #     with cubes:
    #         rep.randomizer.scatter_2d(surface_prims=[plane_l, spheres, cubes], check_for_collisions=True)
    #     return cubes.node

    def place_worker():
        spheres = rep.get.prims(semantics=[('class', 'sphere')])
        worker = rep.create.from_usd(WORKER, semantics=[('class', 'worker')], count=20)
        workers = rep.get.prims(semantics=[('class', 'worker')])
        with workers:
            rep.randomizer.scatter_2d(surface_prims=[plane_l, spheres], check_for_collisions=True)
            #rep.randomizer.scatter_2d(surface_prims=plane_l, check_for_collisions=True)
        return workers.node

    rep.randomizer.register(place_sphere)
    # rep.randomizer.register(place_cube)
    rep.randomizer.register(place_worker)

    with rep.trigger.on_frame(num_frames=5, rt_subframes=60):
        rep.randomizer.place_sphere()
        rep.randomizer.place_worker()

OK - i’ll look into this.

thanks

I’m also having an issue with it. I’m working on a fix for it - will keep you posted.

Do you need a fix for this immediately? I can make it work for that specific usd file but I’m worried it may not work for some other usd files. And so to really fix it right I need to test it with a bunch of them, which will take time for me to put together.

We have created a ticket internally for this bug -

-Henry

Nope its not urgent

1 Like

@frederick.liew I have all of these fixed/updated in replicator 1.9.1. Should be out with next release of Code (later this month? not exactly sure)

1 Like

okie thanks