Extract all instances in the hierarchy - Solaris

   Views 1338   Replies 6   Subscribers 1
User Avatar
Member
11 posts
Joined: 4月 2022
Offline
Hello!

I have a big usd set with multiple instance ( PointInstancer ) in the hierarchy.
I need to extract all of them procedurally.
In extractinstances or modifypointinstances in the "instances" parameter

/**/*_instance
This works 90% because we usually add the suffix.

A more safe selection would be:
%type(PointInstancer)[*]

But it doesn't seem to be the correct way.

The resulting string in the "instances" parm should be:
/root/level1/tree_instance[*]
/root/level1/bush_instance[*]
..
in order to work correctly

and I think what I'm trying above results in this instead:
/root/level1/tree_instance
/root/level1/bush_instance
[*]



Thanks for the help!
Edited by wlvl_gv - 2024年6月3日 06:53:25
User Avatar
Member
11 posts
Joined: 4月 2022
Offline
PS.

I tried this piece of python code in the parameter, but it errors with infinite recursions if I do it on the extractinstance node itself ( on a spare string parm ). It seems to work if I do it on a null and channel reference the parm.
It seems to be a bit slow to compute though. Are there any more efficient ways?

import hou
from pxr import Usd, UsdGeom

# Get the current stage from the current Solaris node
stage = hou.pwd().stage()

# Check if the stage is valid
if stage is None:
    raise ValueError("Error: No valid USD stage found. Please ensure you are in the correct context and the node has a valid USD stage.")

# Initialize an empty list to store the paths of PointInstancer primitives
point_instancers = []

# Function to check if a prim is visible
def is_prim_visible(prim):
    # Check if the prim has an attribute for visibility and it is set to 'invisible'
    visibility_attr = prim.GetAttribute('visibility')
    if visibility_attr and visibility_attr.Get() == 'invisible':
        return False
    return True

# Traverse through all prims in the stage
def traverse_stage(stage):
    for prim in stage.Traverse():
        # Skip deactivated prims
        if not prim.IsActive():
            continue
        # Skip invisible prims
        if not is_prim_visible(prim):
            continue
        # Check if the prim is a PointInstancer
        if prim.GetTypeName() == "PointInstancer":
            point_instancers.append(prim.GetPath().pathString + '[*]')
    return point_instancers
    
# # Call the function to traverse the stage
# traverse_stage(stage)

# # Print the list of PointInstancer primitives
# print("List of PointInstancer Primitives:")
# for path in point_instancers:
#     print(path)
    
    
    
# Call the function to traverse the stage
list = traverse_stage(stage)
list = " ".join(list)
return list

# ## Print the list of PointInstancer primitives
# print("List of PointInstancer Primitives:")
# for path in point_instancers:
#     print(path)
Edited by wlvl_gv - 2024年6月3日 09:01:44
User Avatar
Member
11 posts
Joined: 4月 2022
Offline
Attached an example hip of the production workflow I am trying to improve.


Import asset USD file (proxy):

The set comes from the asset department, a mix of maya and houdini usd prims and instances. ( ie. trees, bushes, houses lightpost, shacks etc )

Import the USD in SOP:
Unpack the USD to the desired level in order to get 1 packed usd per item that I want to sim.
Create a "usd_prim_unique" attribute with a combo of usdIndex and usdSrcPrimPath ( this will be unique for each instance, check vex code below )
These items will go into a large scale RBD sim. ( no fracturing, 1 item will be 1 packed prim in DOP )
OUT_usd_packed_prims_rest


Unpack the USD to Polygons:
configure for RBD, sim, extract sim points from RBDsolver.

Transform original USD in SOP:
Use Transformpieces on the OUT_usd_packed_prims_rest with the RBD sim points.
Now I have USD packed prims animated in SOP.

Export in LOP:
Import original asset USD from disk.
Use "modify point instance" to add transforms on the instances, using the USD packed prims animated in SOP (match by usd_path_unique)
Use "sop import" to add transforms on the non-instance usd prims, using the USD packed prims animated in SOP
(match by path)

DONE


s@usdPrimPath=primintrinsic(0,"usdPrimPath",@primnum);
s@usdSrcPrimPath=primintrinsic(0,"usdSrcPrimPath",@primnum);
i@usdIndex=primintrinsic(0,"usdIndex",@primnum);
s@usd_path_unique =  s@usdPrimPath + "_" + s@usdSrcPrimPath + "_" + itoa(i@usdIndex);





This workflow WORKS.
I am wondering if there are any more efficient ways to do it.
I also have a few questions:
1-a faster method to collect all instancers present in the USD ( at the moment I am using the Python code posted in previous post)

2-How can I prune a selection of USD instances based on some sort of ID?
The idea is that if I blast some of the USD packed prims in SOP , I do not want to export those in LOP, hence prune them.
Is there a way to extract the usdIndex in LOP ? That would do the trick I think.

Thanks in advance for any help or ideas

Attachments:
PI_Match_Edits_production_example_v03.hip (825.4 KB)

User Avatar
スタッフ
431 posts
Joined: 2月 2008
Offline
This is now supported in 20.5
User Avatar
Member
12 posts
Joined: 10月 2021
Offline
Thanks npetit, great addition!!
The Prune/Internal SOP works great.

Is there any usd attributes that are 'forbidden' or could confuse the 'Modify Point Instances'.
I can make it work for some of our set.usda, but some of them errors in one of the python SOPs inside.
sopnet/get_attributes


Python error: Traceback (most recent call last):
File "", line 78, in 
File "", line 60, in getAttributes
File "C:\PROGRA~1/HOUDIN~2.5/HOUDIN~1.332/houdini/python3.11libs\houpythonportion\Geometry.py", line 382, in addAttrib
return orig_method(
^^^^^^^^^^^^
File "C:\PROGRA~1/HOUDIN~2.5/HOUDIN~1.332/houdini/python3.11libs\hou.py", line 43884, in addAttrib
return _hou.Geometry_addAttrib(self, *args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
hou.OperationFailed: The attempted operation failed.
An attribute with this name already exists


I tried commenting the creation of the __hasid attribute, or to create it above the python node. This makes the error goes away, but then a mismatch of the ids cause only some of the instances to be moved/pruned.


I'm trying to create a test set that reproduce the issue, but atm simpler sets all works!


H 20.5.332
Edited by wlvl_r - 2025年4月7日 12:21:00
User Avatar
Member
12 posts
Joined: 10月 2021
Offline
I am experiencing a weird behaviour on the Modify Point Instances Lop (modifypointinstances)
in Houdini 20.5 VS 20.0

The same USD file works as expected on H 20.0.653 and does not in H 20.5.332
Attached a few screenshots of the expected vs not behaviour.
Attached also an example hip of what im doing ( no usd provided )

Unfortunately I cannot provide the usd file as is part of production.
I am still trying to create a new USD test file that replicate the situation but so far no luck


Any pointers on what could cause this is highly appreciated. Thanks!

PS. seems like something is messing up the id matching which causes both the transformation and the deletion of the instances to fail
Edited by wlvl_r - 2025年4月24日 12:07:14

Attachments:
h20.5_instance_original.png (2.0 MB)
h20.5_instance_trans.png (2.1 MB)
h20.5_instance_trans_wtdelete.png (1.5 MB)
h20_instance_original.png (2.3 MB)
h20_instance_trans.png (2.2 MB)
h20_instance_trans_wtdelete.png (1.8 MB)
example_hip.hip (452.1 KB)

User Avatar
スタッフ
431 posts
Joined: 2月 2008
Offline
Without an example it's really hard to tell what's going on.
Could you submit a bug report - and if so, would you be able to attach the USD files to it there so they remain confidential?
  • Quick Links