Trying to write a .vex for hou.runVex()

   1170   3   1
User Avatar
Member
51 posts
Joined: April 2011
Offline
I am struggling with some performance issues within the HOM library in Python and know that the implementation of what I'm trying to do is orders of magnitude more efficient in VEX, but the project is 100% limited to Hython. The Hython shell is being executed by an external program which is going to be feeding commands and retrieving files written by Hython to disk. This is a hard restriction on any solutions.

In Hython, the code I am using is this:
pointList = [[pt.number() for pt in pr.points()] for pr in geo.prims()]

I have been in touch with the engineering staff for SideFX about the performance issues and there is not much that can be done. The prim.points() function takes about 13 microseconds to run, which is several orders of magnitude larger than it would take to just load a list. Behind the scenes it is running over generators for hou.Prim.verticies() which then is resolved back to the points.

What I want to do is use VEX's primpoints(geo, primnum) function to get the list. A user over on Odforce did some tests and found that the process of aliasing the point numbers to a list of ints using the function is way better, but I cannot use a wrangle node in the project. No verbs for anything which would do what I need.

So this leads me to where I am now. hou.runVex(). This function takes a .vex file and a dictionary of values and spits out a dictionary with the results. I have gotten my vex code to compile (it's wrong though) and I have figured out how to get data to pass to it through the function. The issue is that I cannot figure out how to declare a variable as a geometry object to be handed over. I have the HOM objects (which are loaded from disk) which I would like to pass to the primpoints() as the 'file' attribute. This should be doable as it is able to be done in a wrangle node, but I cannot for the life of me figure out how.

vfl I have now:
cvex pointNumbers(int geo = 0, int primnum=0; export int pointList[]={}) {
	pointList = primpoints(geo, primnum);
}

Python I want to be using:
pointList = [hou.runVex('pointNumbers.vex', {'geo':geo, 'primnum':pr.number()}) for pr in geo.prims()]

I am also using Pandas on the Python side, so it may be an option to hand the whole geometry and handle the calls inside VEX, hand out a list of point numbers and an index matched list of prim numbers, then using Pandas on the Python side to stack it all, but for now I just need the hou.runVex() function to actually process. The error I get comes from not being able to type the VEX geo variable in a way to accept the geo HOM object. What do I need to do to the object to pass it to the VEX variable?
User Avatar
Member
122 posts
Joined: June 2019
Offline
For this particular case you can express this network as a verbs sequence:


Essentially:
1. Enumerate points by index for example
2. Split points
3. Sort points with option By Vertex Order

Now your points are linear vertices of original geo and index attribute its point number.

To get this attribute efficiently you can use hou.Geometry.pointIntAttribValuesAsString
(If you need list of lists you can promote index attribute to primitives as Array Of All though not sure if buffer functions can be applied for arrays attribute)

For more general case if you're on 19.0 you can use Invoke Graph SOP. Basically construct a subnet containing wrangle. Then use Attribute From Parameters SOP with Points From Subnetwork method. Save the output of the latter SOP to the file.

Now you have a representation of your subnet in geometry file.

You can then load this geometry from file (hou.Geometry.loadFromFile) and use Invoke Graph verb with Invoke Explicit Outputs/Inputs method and First Point as Output Type. It's like invoking a compiled block but stored in geometry. You can probably even modify wrangle code after you load graph as a Geometry (it would be on the one of the dict attribute at the point representing wrangle snippet).

(I'm not sure if it's technically possible to use hou.runVex in sop context and feed it geometry)
Edited by elovikov - May 4, 2022 18:31:31

Attachments:
pts_to_verts.png (94.5 KB)

User Avatar
Member
51 posts
Joined: April 2011
Offline
Ok, that is both impressive and amazing. I'm pretty sure that all of this will work for my use case in a really performant way (at least way better than the HOM code is doing). I hadn't seen the Invoke Graph SOP, so this is probably going to blow the project wide open. Thank you so much for the help.

(I actually kinda figured it wouldn't be possible as the geometry in Hython is python objects, but one can dream... or at least dream that they would make thing interoperable)
User Avatar
Member
51 posts
Joined: April 2011
Offline
Man, just got through with doing some unit tests with using the verbs you suggested and they are better than we could have dreamed. It ended up just needing to be Enumerate and Attrib Promote set to "list of all". Faster than anything we have been able to implement using HOM by an order of magnitude. We owe you a beer wonderful mysterious stranger.

I am still going to look into the other things you mentioned for future projects, but the enumerate -> promote got us there for now.
  • Quick Links