Updating node's attributes dynamically from code

Hello,

I wanted to use Replicator so that it either updates colours of all my prims individually (i.e. assigns a different colour to each prim) or have them all assigned to the same colour. I populated list of prims using rep.get.prim_at_path and then, I update inputs:paths attribute with the paths. However, I noticed that as soon as I pass “/Replicator” as the path (to update all prims to the same colour), Replicator maintains this setting despite me updating intputs:paths attribute of my prim_at_path node.

I have uploaded an example Python code to illustrate the problem. What happens, in the first 10 frames each object has different colour assigned as expected. Then, for another 10 frames, they all receive the same colour. I would then expect the process to be repeated, i.e. each object to have colour assigned separately, but it is not the case. Colours of all prims is updated to the same value, despite changes to inputs:path attribute (see printed output of get_attribute(“inputs:paths”).get() )

I would very much appreciate if someone could advise me on how to solve this problem. I would prefer to modify prims’ properties in a single simulation rather than restarting Replicator each time with new settings. Furthermore, I’d prefer not to change the layer as I’d need to re-load all assets which may be a bit time-consuming.

Many thanks,
Mateusz

edit: I forgot to mention that I’ve also tried creating two separate prim_at_path nodes for individual objects and for whole stage, and control the execution via omni.graph.action.Branch, but similarly, updating “inputs:condition” attribute didn’t seem to impact the execution paths. I also noticed that by default those multiple prim_at_path nodes were connected to each other, so I used connect and disconnect methods to wire all nodes.

test.py (2.3 KB)

Hello,

I did some more investigation, and it seems that when I want to change multiple prims colour at the same time (i.e. rep.get.prim_at_path([‘/Replicator’])), it sets the Strength of materials to ‘Stronger than Descendants’. If I change it manually in the editor to ‘Weaker than Descendants’, individual prims change colours to random colours previously assigned to them.

So my question now is, how can I modify materials strength from Python? It doesn’t seem to be a property I could change automatically.

I realised that I could overcome it by generating a random colour once, setting it as upper and lower limit to another uniform distribution, and populate it with a count equal to my prims. Then I would have them all in one colour, but seems as a overkill to me. What are your thoughts?

Thanks,
Mateusz

And just as I posted my previous message, I found a solution! When browsing source code I found SetMaterialStrength command which solved the above problem. The example code which does the trick:

omni.kit.commands.execute(
    "SetMaterialStrength", 
    rel=stage.GetPrimAtPath('/Replicator').GetRelationship('material:binding'), 
    strength=UsdShade.Tokens.strongerThanDescendants if all_prims else UsdShade.Tokens.weakerThanDescendants)

If I may make a suggestion, I would add a tooltip in properties for “Materials on selected model” explaining what they are and how they can be modified.

Thanks,
Mateusz

Hello Mateusz,

I’m glad you found a solution to your problem.

You might also want to look at the Replicator API and tutorials, there is a section on changing colors

Randomizer Examples — extensions latest documentation (nvidia.com)

Using your code example, you could simplify as:

            torus = rep.create.torus(semantics=[('class', 'torus')] , position=(-2, 0 , 0))
            sphere = rep.create.sphere(semantics=[('class', 'sphere')], position=(0, 0, 0))
            cube = rep.create.cube(semantics=[('class', 'cube')],  position=(2, 0 , 0) )

            shape_group = rep.create.group([torus, sphere, cube])
            with shape_group:
                     rep.randomizer.color(colors=rep.distribution.uniform((0, 0, 0), (1, 1, 1)))

Also, as you can see from the example, you can find/get prims in an easier manner than traversing the stage or node inputs

shapes = rep.get.prims(semantics=[('class', 'cube'), ('class', 'sphere'), ('class','torus'])

Hi Dennis,

Thanks for your post. This is the example I based my on. The problem I had was that in this case randomizer assigns different colour to each object inside shape_group. What I wanted to achieve is that after a number of iterations to change the behaviour so that all objects would be assigned to exactly the same material/colour. Then, after some more iterations, I wanted to move back to assigning new colour on per object case.

In any case, the problem is solved and I look forward to using replicator. Thanks!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.