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!
Thanks for reading me!
Read how much primitives are in a solaris node.
2393 8 1- RodrigoMartin
- Member
- 24 posts
- Joined: Nov. 2019
- Offline
- Soothsayer
- Member
- 874 posts
- Joined: Oct. 2008
- Offline
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
Jobless
- RodrigoMartin
- Member
- 24 posts
- Joined: Nov. 2019
- Offline
SoothsayerHi!
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.")
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!
- Soothsayer
- Member
- 874 posts
- Joined: Oct. 2008
- Offline
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.
or if you are feeling more adventerous:
There are also examples here: https://openusd.org/release/tut_traversing_stage.html [openusd.org]
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 visited.add(id(module)) 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
Jobless
- RodrigoMartin
- 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 visited.add(id(module)) 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!
- Soothsayer
- Member
- 874 posts
- Joined: Oct. 2008
- Offline
It's not complete but here are some ideas to filter it:
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.
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()] if prim.IsLoaded(): 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
Jobless
- Soothsayer
- Member
- 874 posts
- Joined: Oct. 2008
- Offline
How about this? (You need to make a parm called nodepath and drag your node into it)
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
Jobless
- elovikov
- Member
- 130 posts
- Joined: June 2019
- Offline
You probably can use prim stats from LopNode:
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
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
- BryanRay
- 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]
https://github.com/PixarAnimationStudios/USD/blob/v22.11/pxr/usd/usdShade/testenv/testUsdShadeBinding.py [github.com]
I like to search for things on Github, and filter for the Python language; most of the time points me to a unit test in Python that shows how to do something.
-
- Quick Links