APEX and Python - how to find point from node?

   1339   14   2
User Avatar
Member
25 posts
Joined: Jan. 2017
Offline
Hi all, has anyone working with APEX graphs in Python found a solid method for matching geometry point IDs to their corresponding APEX nodes (in the "graph" Python object)?

It seems to match one to one between geometry point ID and APEX node ID, until you add a subgraph, then the order is sent out of whack by all the points packed into the subgraph that don't have corresponding geometry points.

EDIT: Currently I'm matching by name, but this requires nodes inside subgraphs not to share names with nodes in the parent graph, which isn't ideal - "parms" and "output" will by default conflict in any subgraph, and I don't think output nodes work properly with a different name.
Edited by danfitz82 - Dec. 13, 2023 05:14:15
https://www.noad.co [www.noad.co]
User Avatar
Member
219 posts
Joined: March 2023
Offline
Very probable that Apex Node ID are generated on the fly when it converted from geometry to apex graph, so there is simply no way to do this match from the point ID.

if I understand, are you trying to edit an apex graph directly by modifying the geometry instead of convertir the geometry to an apex graph where you can then use the API ?
Edited by Jacquesf - Dec. 13, 2023 05:23:48
Head of Pipeline @ LightVFX
User Avatar
Member
25 posts
Joined: Jan. 2017
Offline
Jacquesf
if I understand, are you trying to edit an apex graph directly by modifying the geometry instead of convertir the geometry to an apex graph where you can then use the API ?

Ideally I'd like to just use the API if it's possible, but I'm using a combo of APEX API and geometry - which seems to be how SideFX is doing things internally in their Python (eg finding what callback a node has is based on point attributes, looking through ports is based partly on vertex info). Of course it's all undocumented so I'm learning by sifting through code, and it's very likely I've missed things.
https://www.noad.co [www.noad.co]
User Avatar
Member
219 posts
Joined: March 2023
Offline
I don't think you should have to rely on the geometry once you converted it to a graph, you can use the graph.matchNode() function that can support any of the pattern you can use in the findNodes node in an apex graph, so for exemple "%callback(TransformObject)" to find all TransformObject.
Head of Pipeline @ LightVFX
User Avatar
Member
213 posts
Joined: June 2023
Offline
danfitz82
(eg finding what callback a node has is based on point attributes, looking through ports is based partly on vertex info).

In this very particular case:

finding a callback of a node: graph.callbackName(id)

iterate over ports: graph.getOutputNodes(id) or graph.getInputNodes(id)

You can work on geo, or you can work on graph. But I really don't think you should try to work on both at the same time. Next time if SideFX changes how graph.loadFromGeometry() works your code will be broken. And you will need to sync between graph and geo constantly.
Edited by kodra - Dec. 13, 2023 06:18:53
User Avatar
Member
25 posts
Joined: Jan. 2017
Offline
kodra
finding a callback of a node: graph.callbackName(id)

iterate over ports: graph.getOutputNodes(id) or graph.getInputNodes(id)

Thank you!

kodra
But I really don't think you should try to work on both at the same time. Next time if SideFX changes how graph.loadFromGeometry() works your code will be broken.

Absolutely, and it's not been much fun doing it this way, but so much of the code in the APEX library code does it this way I thought that must be the way to do it. I also forgot as we're in Python I can print all the methods in the "graph" object, so a bit of a face palm moment for me, I should have much better access to the API now (still subject to change I'd expect until it gets documented!)
https://www.noad.co [www.noad.co]
User Avatar
Member
219 posts
Joined: March 2023
Offline
I always believe we shouldn't consider why and how sidefx do certain thing as 'the' way to do thing, because at the end of the day, it was simply one way they choosed along many other. they are either suggestion, idea, or the only way they could have done it back when they started.

It possible that you look at are early work from sidefx that was done before they even have an API to work to begin with.
Edited by Jacquesf - Dec. 13, 2023 07:25:30
Head of Pipeline @ LightVFX
User Avatar
Member
25 posts
Joined: Jan. 2017
Offline
Jacquesf
I always believe we shouldn't consider why and how sidefx do certain thing as 'the' way to do thing, because at the end of the day, it was simply one way they choosed along many other.

Sure, and it's all beta now so everything is in flux, and I'm only asking for trouble learning this way before proper documentation exists - but in my defense as this stuff is so new the only examples of usage for many features are what's in the library code. I know that'll get sorted out eventually, but it's much too exciting to wait for that!
https://www.noad.co [www.noad.co]
User Avatar
Member
219 posts
Joined: March 2023
Offline
I think we should be safe with the current state of the API, it possible certain function change, like the way we load geometry into a graph, but the main feature of the graph itself (addnode, find, etc) there not much reason for them to change even in the long run.
Head of Pipeline @ LightVFX
User Avatar
Member
213 posts
Joined: June 2023
Offline
danfitz82
Sure, and it's all beta now so everything is in flux, and I'm only asking for trouble learning this way before proper documentation exists - but in my defense as this stuff is so new the only examples of usage for many features are what's in the library code. I know that'll get sorted out eventually, but it's much too exciting to wait for that!

If there will ever be proper documentation. Houdini has quite a lot Python API that are never documented officially. stateutils, soptoolutils, kinefx, etc, etc...

You should probably send an RFE specifically for apex module is you consider it important, since SideFX evidently considers documentation of any Python module not under hou is second class citizen. (Perhaps they believe few people will actual use them, or they think people like to torture themselves reading the tens of thousands lines of "examples"...)
Edited by kodra - Dec. 13, 2023 07:55:28
User Avatar
Staff
64 posts
Joined: May 2021
Offline
working with the functions of the graph object is definitely the right approach and that API should be stable. And yes that section will be documented
User Avatar
Member
25 posts
Joined: Jan. 2017
Offline
I've had some success removing dependencies on geometry info in my code, aiming to just use the APEX Python API, but here are a couple things I haven't figured out yet:

- How do we find the subgraph from a subnet node? (so I can copy it with "addSubnet")
- How do we access the position and colour info of nodes? This is less important but still helpful, as I'm copying nodes it would be useful to have them copied into the same place for easier debugging - I know that info is stored in the APEX graph somewhere as it's written back to the geometry by writeToGeometry, but I haven't found it so far. I thought it might be in "getNodeProperties" or "properties" but I just get empty APEX Dictionary objects from those.

Those are the things at the moment I'm still doing with geo, has anyone else been able to do this with the API?
https://www.noad.co [www.noad.co]
User Avatar
Member
7743 posts
Joined: July 2005
Offline
danfitz82
- How do we find the subgraph from a subnet node? (so I can copy it with "addSubnet")

Try calling the apex.Graph.callbackName() for the node, which you can then use it with apex.Registry.getSubGraph().

danfitz82
- How do we access the position and colour info of nodes?

I think this is currently missing. Please log RFEs for them. Copying might be best as geometry right now since they're merely the P and Cd point attributes.
User Avatar
Member
213 posts
Joined: June 2023
Offline
It's a bit mysterious since we can set the color with setNodeColor(), but not get it.
Edited by kodra - Dec. 17, 2023 01:05:42
User Avatar
Member
25 posts
Joined: Jan. 2017
Offline
In answer to my original question, while I'm still using a mix of geo/APEX API - to get a more solid match between the geo points and the APEX nodes, regardless of any nodes with the same name inside subgraphs, we can match APEX nodes by path instead of by name, simply by adding a forward slash at the start - eg in Python do something like:
graph.matchNodes(f"/{name}")
https://www.noad.co [www.noad.co]
  • Quick Links