### Read how much primitives are in a solaris node.

2064   8   1
Member
24 posts
Joined: Nov. 2019
Offline
Hi! I am trying to cound how much primitives are in a node, as a way to detect if the variant I am looking for exist, but I don't know how to read this, I have a switch with the high lod and the low lod, and I want to detect when the 2nd node doesn't have low variant.

I achieved some progress by using the explore variants in a way that if there is now low variant it will show empty.

I don't know if it's there other way to do this cleaner, but this is what I have right now!

Final Layout.
Member
871 posts
Joined: Oct. 2008
Online
In a Python Lop, does this get you what you want?

```node = hou.pwd()
stage = node.editableStage()

# Add code to modify the stage.
# Use drop down menu to select examples.

yournode =  hou.node('/stage/null5').stage().GetPrimAtPath('/arcsmoke')

def count_prims(node):
count = 0
for child in node.GetChildren():
count += 1
count += count_prims(child)
return count

prim_count = count_prims(yournode)
print("The node has", prim_count, "prims.")
```
--
Jobless
Member
24 posts
Joined: Nov. 2019
Offline
Soothsayer
In a Python Lop, does this get you what you want?

```node = hou.pwd()
stage = node.editableStage()

# Add code to modify the stage.
# Use drop down menu to select examples.

yournode =  hou.node('/stage/null5').stage().GetPrimAtPath('/arcsmoke')

def count_prims(node):
count = 0
for child in node.GetChildren():
count += 1
count += count_prims(child)
return count

prim_count = count_prims(yournode)
print("The node has", prim_count, "prims.")
```
Hi!

Yes it works, but there is a thing that I don't understand, in the viewport, having just 1 asset with 1 variation write "1 primitive" but the code reads 78, I understand that the node is reading all the primitives in the layer, so "object/geo_grp/body_grp/geometry" count as 5 primitives, one for each level. (I don't know exactly how to explain it in text but I understand the concept)

I imagine that running on this loop a filter with the name or the type of primitive will give the correct result I am looking, but I can't find the documentation for the functions you used, searching on the houdini documentatio for example stage().GetPrimAtPath() don't give a clear result.

Is there an external documentation or any list of functions I can look at for this? I think I am missing something and that all of this would be easier with that (if there is somewhere)

Thank you for the previous script too, I am one step closer to make all work!
Final Layout.
Member
871 posts
Joined: Oct. 2008
Online
There are docs but I'm afraid it's not necessarily easier:

https://openusd.org/release/api/class_usd_stage.html#a6ceb556070804b712c01a7968f925735 [openusd.org]

Somebody correct me if I'm wrong but as far as I can work out it's a c++ api and the python bindings are generated from this, meaning that you can adapt them 'in a simple and straightforward way'.

Now, you could try this in python to see what's in the pxr usd module and then dig around in the docs for it.

```from pxr import Usd
print(dir(Usd))
```

or if you are feeling more adventerous:

```node = hou.pwd()
stage = node.editableStage()

def list_module_contents(module, prefix="", visited=None):
contents = []

# Initialize the visited set if it's not provided
if visited is None:
visited = set()

# Prevent infinite recursion by checking if the module was already visited
if id(module) in visited:
return contents

for name in dir(module):
# Check if the attribute is readable
if not hasattr(module, name):
continue

attr = getattr(module, name)
full_name = f"{prefix}{name}"

if isinstance(attr, type):
# If the attribute is a class, recursively list its contents
contents.extend(list_module_contents(attr, f"{full_name}.", visited))
else:
contents.append(full_name)

return contents

from pxr import Usd

# List everything in the Usd module recursively
contents = [i for i in list_module_contents(Usd) if '__' not in i]

print(contents)
```

There are also examples here: https://openusd.org/release/tut_traversing_stage.html [openusd.org]
--
Jobless
Member
24 posts
Joined: Nov. 2019
Offline
Soothsayer
There are docs but I'm afraid it's not necessarily easier:

https://openusd.org/release/api/class_usd_stage.html#a6ceb556070804b712c01a7968f925735 [openusd.org]

Somebody correct me if I'm wrong but as far as I can work out it's a c++ api and the python bindings are generated from this, meaning that you can adapt them 'in a simple and straightforward way'.

Now, you could try this in python to see what's in the pxr usd module and then dig around in the docs for it.

```from pxr import Usd
print(dir(Usd))
```

or if you are feeling more adventerous:

```node = hou.pwd()
stage = node.editableStage()

def list_module_contents(module, prefix="", visited=None):
contents = []

# Initialize the visited set if it's not provided
if visited is None:
visited = set()

# Prevent infinite recursion by checking if the module was already visited
if id(module) in visited:
return contents

for name in dir(module):
# Check if the attribute is readable
if not hasattr(module, name):
continue

attr = getattr(module, name)
full_name = f"{prefix}{name}"

if isinstance(attr, type):
# If the attribute is a class, recursively list its contents
contents.extend(list_module_contents(attr, f"{full_name}.", visited))
else:
contents.append(full_name)

return contents

from pxr import Usd

# List everything in the Usd module recursively
contents = [i for i in list_module_contents(Usd) if '__' not in i]

print(contents)
```

There are also examples here: https://openusd.org/release/tut_traversing_stage.html [openusd.org]

Wow, I think this weekend I will have some fun diving into this, I'm sure I will hit some walls in the path but progress is progress at the end!

Thank you so much! This is great!
Final Layout.
Member
871 posts
Joined: Oct. 2008
Online
It's not complete but here are some ideas to filter it:

```node = hou.pwd()
stage = node.editableStage()
from pxr import Usd
# Add code to modify the stage.
# Use drop down menu to select examples.

xs = [x for x in stage.Traverse()]
y = xs[0]
for prim in xs:
children = [c for c in prim.GetAllChildren()]
models = [m for m in children if m.IsModel()]
print(prim, prim.GetTypeName(), models)

#print(dir(y))
```

Unquote that last line and you can see what you can access on a prim, then use the docs to get some better ideas of what arguments, if any, it wants.
Edited by Soothsayer - May 5, 2023 08:25:36
--
Jobless
Member
871 posts
Joined: Oct. 2008
Online

```from pxr import Usd

node = hou.pwd()
stage = node.editableStage()

user_node_path = hou.parm('nodepath').eval()
user_node = stage.GetPrimAtPath(user_node_path)

child_counts = {}

for child in user_node.GetChildren():
child_type = child.GetTypeName()

if child_type in child_counts:
child_counts[child_type] += 1
else:
child_counts[child_type] = 1

print(f"USD Prims child count by type for node: {user_node_path}")
for child_type, count in child_counts.items():
print(f"  {child_type}: {count}")
print("=============================")
```
Edited by Soothsayer - May 5, 2023 10:45:32
--
Jobless
Member
126 posts
Joined: June 2019
Online
You probably can use prim stats from LopNode:

```hou.node("/stage/your_node").stagePrimStats()["Mesh:Total"]

# or even this one to get polygon count

hou.node("/stage/your_node").stagePrimStats(do_geometry_counts=True)["Mesh (Polygons):Total"]
```

For more complicated stuff houdini has its own pretty robust solution for stage traversal and prim queries: https://www.sidefx.com/docs/houdini/solaris/pattern.html [www.sidefx.com]

It's usable in python via hou.LopSelectionRule
Staff
43 posts
Joined: March 2022
Offline
Some advice I got from goldleaf a while ago has served me well:

Okay so I've found the best way to learn Python and USD is the unit tests on GitHub. For example, here are some tests for Primvars, and Materials:

https://github.com/PixarAnimationStudios/USD/blob/3abc46452b1271df7650e9948fef9f0ce602e3b2/pxr/usd/usdGeom/testenv/testUsdGeomPrimvar.py#L512 [github.com]