(rant) UE style of nodes stacking is a bit weird

   5187   47   6
User Avatar
Member
219 posts
Joined: March 2023
Offline
kodra
APEX's "graphs editing graphs" nature gives me the same vide: code as data, little to no type safety, passing strings around, passing dict as parameters around, extra layer of indirectness...

Again, that would be a problem if you consider Apex as a programming language, which it is not.
Apex have a lot problem linked to UX indeed, debugging it is kind of a nightmare, the requirement to execute apex in a deferred state definitely don't help.
as a programmer with experience, I've seen worse, and I can get around, I know it not gonna be the case of everybody else.
but I like to see the potential in thing rather than how they are right now, apex is a new system, it haven't had time to show it's proof, and I definitely don't people wanting to use it today.
I expect sidefx to be perfectly aware of it, and I would bet anything that the main focus for h20.5 will be on better user experience with Apex.
there is a few 'hidden' debugging tool that tell that it possible to get all the state of an apex graph as it being worked on, so I have no doubt we'll be able to see in realtime what an apex graph do as you build it (and if they don't, I'll do it myself).

now I wanna compare apex to something else, to show you that in reality, it not more different than something that have been used for at least 20 year.


apex as it core is nothing but an engine that can run node and pass through data between each.
Forget the notion of code as data, forget the notion of apex being stored as geometry, data is data, it don't matter how it stored, and it don't matter how it saved
an apex graph could be a yaml file, a json file, or a binary file so it trully don't matter that right now, it stored as geometry, data IS data and have no meaning by itself.
what give meaning to data is how you interpret it. when you want to run an apex graph, you first run the data (that is currently an houdini geometry) and translate it into an apex graph and then you pass that graph to the apex engine. you could write an json to apex translate (assuming there an api for that)

how you build data also don't matter, right now, sidefx present apex as being capable of writting apex graph, that one way of writting data, there is an infinite way you could write apex data :
use python to make an apex graph
use vex to write an apex graph
use an apex graph to wriet an apex graph
use javascript to write an apex graph
use an AI to write an apex graph
go on indefinitely.

Apex do not care how you build the data, it an engine to run node and pass data around.
how you use apex, and how apex work is 2 very different thing.
you can run an apex graph using python, you can run an apex graph using the invoke apex graph sop node, you could in theory run apex graph in C++. it an engine, it don't care where and why it run, it sole purpose it to run a graph that we gave it , with input data and output data.

apex wouldn't be capable of any interaction with the viewport by itself, it the tool that sidefx made for the animation state, the rigscript component, and whatever else they made that make apex run as a rigging and animation tool.
alone, apex is just an Input-Output machine

represented as code that what apex is (simplified, apex also have partial evaluation capability to run only a subpart of the graph):
graph = loadDataIntoGraph([json, yaml, binary, hou.Geometry, Whatever]);
input = {string: "hi"};
result = runapex(graph, input);

that all, that really all there is to apex being apex, what give the context of rigging to apex is all the code around that little function.

where I'm going with that ?

lets go to maya for a bit.
Have you ever opened the node editor in maya ? what do you see ? node, node with connection, that all you see, there nothing else, it just a bunch of node with a bunch of connection, similar to apex, maya core is the dependancy graph, maya is also a input-output engine.
the key difference in maya dependancy graph vs apex is that maya build every tool they have around the dependancy graph, every one of them :
you want to create a bone, it add node to the dependancy graph, you want to create constraint : it add node to the dependancy graph, and you go one for every tool that exist , maya tool are just a dependancy graph builder.

apex could replace the maya depandancy graph and it would work the same way, how you use the engine is what matter.

disclaimed : I know that apex and the dependancy graph are slightly different, as it more of a plug to plug compilation more than a node to node like apex, which is why in maya node can connect into themselve, but that beside the point.


so, apex having virtually the same capability as maya, all of what maya can do, apex can do it too.
that why apex is a framework, and it don't matter how you use it, it the tool around apex that define how apex will be used.

and Apex is NOT A PROGRAMMING LANGUAGE it not vex, it not vop.
Edited by Jacquesf - Dec. 12, 2023 10:00:08
Head of Pipeline @ LightVFX
User Avatar
Member
213 posts
Joined: June 2023
Offline
how you build data also don't matter, right now, sidefx present apex as being capable of writting apex graph, that one way of writting data, there is an infinite way you could write apex data :
use python to make an apex graph
use vex to write an apex graph
use an apex graph to wriet an apex graph
use javascript to write an apex graph
use an AI to write an apex graph
go on indefinitely.

By this definition, Python isn't code either. You can use Python to write Python. You can use C++ to write Python. You can use AI to write Python.

Even if you call Apex "data", it's still something that needs to be "executed" at some point, just like Python code. A Python script is string, it can be saved to the disk as a plain text file, but it's still code because the purpose of a Python script is to be executed by Python interpreter.

The main issue about this (among the other issues) is that it separates where you generate "something" and how "something" is evaluated. Which makes debugging much harder. For example, if your Python throws an uncaught exception, it will dump the whole call stack for you and you can know which line causes this exception immediately. But if your Python code is generated by another Python code, you can't pinpoint the problematic line without carefully traversing the whole code generation logic.

You can call this "something" "code" or "data", but it doesn't change the essence of this issue. If I saw the hidden debugger tools you said I might view it differently.

Have you ever opened the node editor in maya ? what do you see ? node, node with connection, that all you see, there nothing else, it just a bunch of node with a bunch of connection, similar to apex, maya core is the dependancy graph, maya is also a input-output engine.

Yes, and the reason I chose Houdini over Maya from the first place is that SOP network is clean, easy to ready, unlike Maya. I'm not the only one who thinks this is Houdini's advantage over Maya:



Perhaps for rigging/animating this kind of evaluation engine is necessary, but I absolutely don't want it to be "the new SOP". If it's the future of Houdini, I hope SideFX makes it clear, so I can cut the loss and completely stop using it now. As I said, the cleanness of SOP is the main reason I chose Houdini. If it's gone then I'm gone. I fully understand people have different mileages, and those who like Houdini for other reasons can continue using it, just not me.

All you said is technically true, and that's what made I concerned about Houdini's future.
Edited by kodra - Dec. 12, 2023 10:08:46

Attachments:
Screenshot 2023-12-12 225944.png (601.3 KB)

User Avatar
Member
219 posts
Joined: March 2023
Offline
kodra
Even if you call Apex "data", it's still something that needs to be "executed" at some point, just like Python code. A Python script is string, it can be saved to the disk as a plain text file, but it's still code because the purpose of a Python script is to be executed by Python interpreter.

I didn't called apex data, I called data 'data'
why apex is not a programming language unlike python ?
python : you know how your code is gonna execute and when, each line after another
apex : there is not definition of how and when a node is gonna be executed, you leave the guessing of how the graph should run to the engine, which start from the requested output plug, and walk itself up to all the required input, and then execute that graph. which is what allow partial evaluation.

that make apex not a programming language, it a smart graph that compute which node need to be execute in which order and pass the data around.


kodra
The main issue about this (among the other issues) is that it separates where you generate "something" and how "something" is evaluated. Which makes debugging much harder. For example, if your Python throws an uncaught exception, it will dump the whole call stack for you and you can know which line causes this exception immediately. But if your Python code is generated by another Python code, you can't pinpoint the problematic line without carefully traversing the whole code generation logic.

you can run your apex graph using the invoke apex graph tool and use the output ERROR mode, that how you know where your apex graph have an issues, so I don't see what the difference between debugging in python and debugging an apex graph. you don't have to use the default "Apex autorig component" as they don't give you a trace :




maybe you lack the insight that you're allowed to do thing differently, don't limit yourself to the existing node or the premade workflow.
Edited by Jacquesf - Dec. 12, 2023 10:28:05

Attachments:
007513_houdini_4jZXBQA0dD_2023-12-12_16-14-39.png (142.6 KB)

Head of Pipeline @ LightVFX
User Avatar
Member
219 posts
Joined: March 2023
Offline
kodra
Perhaps for rigging/animating this kind of evaluation engine is necessary, but I absolutely don't want it to be "the new SOP". If it's the future of Houdini, I hope SideFX makes it clear, so I can cut the loss and completely stop using it now. As I said, the cleanness of SOP is the main reason I chose Houdini. If it's gone then I'm gone. I fully understand people have different mileages, and those who like Houdini for other reasons can continue using it, just not me.

don't worry, apex will not replace regular SOP network, it designed for interactivity, it will allow to make tool that are much faster and efficient and can interact with the viewport, either for rigging, modeling.

Regular sop cannot be replaced by apex and won't go away : you'll lose everything that make sop great like parameter, expression, hda, and so on.

It an addition I personnally been waiting for ever since I started to use houdini, regular sop are amazing but insanely slow if you need complex behavior that work in realtime, if the price to pay is slightly more complicated to read network, I'm all for it!
Edited by Jacquesf - Dec. 12, 2023 10:22:31
Head of Pipeline @ LightVFX
User Avatar
Member
213 posts
Joined: June 2023
Offline
Jacquesf
I didn't called apex data, I called data 'data'
why apex is not a programming language unlike python ?
python : you know how your code is gonna execute and when, each line after another
apex : there is not definition of how when a node is gonna be executed, you start by the output, and you build a list of node you will execute in a specific order on the fly based on the input and output needed

that make apex not a programming language, it a smart graph that compute which node need to be execute in which order and pass the data around.

You've probably forgotten how much modern programming languages are optimized. It's quite common that a compiler builds some kind of dependency graph, traverse through it and delete unused code, so it only runs the necessary lines when the program is actually executed. You can't safely assume a program works like "source code line by line" (especially languages with lots of undefined bahaviors like C/C++, or those can safely throw out side effects like shader languages)

By the way, there are even programming languages that can calculate possible inputs of a function for given output.

If this "build dependency and only execute if necessary" nature is what makes APEX a smart graph, then most programming languages are smart graphs. APEX is just at the smarter end of the spectrum.

(I'm quite sure you're already aware of this, but for people who're interested why you can't assume line-by-line execution, check the last example on this page [en.cppreference.com].)

But this is more a terminology problem.


you can run your apex graph using the invoke apex graph tool and use the output ERROR mode, that how you know where your apex graph have an issues, so I don't see what the difference between debugging in python and debugging an apex graph. you don't have to use the default "Apex autorig component" as they don't give you a trace :

The issue is:

1. APEX is quite low level, which means in most practical cases, you will need higher level tool to generate it. autorig component, Python, AI, whatever... it doesn't matter which tools you use, but you need some tools to author those 5000~10000 node rigs. Hand-authoring APEX graph is like writing assembly directly.

2. But once you start generate it, instead of directly authoring it, the debugging process become indirect. The APEX Invoke node will tell you which node is problematic, but if the node is generated by some upstream node, you still need to read the whole code node generation logic to find the culprit. If you just edit the generated node instead of the generating one, it will create a discrepancy between your node-generation nodes and the final result, similar to what happens when you put a TopoBuild at the end of your elegantly procedural modeling SOPs.

It's definitely not easy to tack.

I can imagine two routes to mitigate this:

1. Make a mid-level library within APEX, as a collection of subgraphs. Similar to how there are many SOPs are based on low level vex code, if APEX's subgraph is at least as good as HDA, perhaps hand-authoring APEX won't be that bad. Subgraph is very clumsy right now... but it's not something fundamentally broken. It lacks some important features now tho, e.g. it needs to "expand loops" (like a mini compile block, but more specific on what it does), otherwise it will be very easy to make non performant graphs and undermine the whole premise of APEX.

2. Make autorig and rig script node smarter so it keeps a "codemap" in metadata that can be used for debugging later. This is a doomed path imo, as the complexity and man-hours needed are skyrocketed... but SideFX has some smart guys so perhaps they can make it work.

Anyway, SideFX probably has the roadmap internally that will prove all my concerns are redundant. Perhaps they already have a better solution than what I randomly typed. But I don't think the issue of APEX is at "just need some more learning materials and UI tweaks" level.
Edited by kodra - Dec. 12, 2023 11:04:37
User Avatar
Member
219 posts
Joined: March 2023
Offline
kodra
You've probably forgotten how much modern programming languages are optimized. It's quite common that a compiler starts with output traverse backwards and delete unused code,

you're describing compilation optimisation, regardless of what it do, it do not change the way your logic work, each line you wrote will do exactly what you expect it to do in the order you wrote it, regardless of the optimisation the compiler did.
apex compile the graph 'once' and then execute node based on the requested output at runtime it is not possible to know in advance which node are gonna be executed in what order, you'd need to specifically describe an execution flow, like unreal engine blueprint and the big white Arrow, that would be real visual programming.

apex only deal with node not programming, it do not create a 'machine code', like vop, vop transcribe node into vex code, that not what apex do here, apex create a chain of operation, passing data between node, the difference seem subtle, but it like having a array of premade function, and that array is build dynamically on demand.

kodra
1. APEX is quite low level, which means in most practical cases, you will need higher level tool to generate it. autorig component, Python, AI, whatever... it doesn't matter which tools you use, but you need some tools to author those 5000~10000 node rigs. Hand-authoring APEX graph is like writing assembly directly.

that up to your workflow, you could keep complaining about the need to make high level tool, or you could ... you know , start making these high level tool now ? I have my own workflow and tool to build apex rig and i'm very comfortable with my 10000+ node rig, with nice color coding and segmented way of debugging a graph, I honestly spend less time rigging than I used to trying to debug a python code to generate maya rig.
get experience today and reap the benefit of being efficient tomorrow.

kodra
2. Make autorig and rig script node smarter so it keeps a "codemap" in metadata that can be used for debugging later. This is a doomed path imo, as the complexity and man-hours needed are skyrocketed... but SideFX has some smart guys so perhaps they can make it work.

There an python state called 'APEX DEBUG' which in theory allow you to see the internal data of every node as they are being executed, I didn't managed to make it work, but it not officially mean to be used by us yet, so wait and see.


kodra
Anyway, SideFX probably has the roadmap internally that will prove all my concerns are redundant. Perhaps they already have a better solution than what I randomly typed. But I don't think the issue of APEX is at "just need some more learning materials and UI tweaks" level.

Trust sidefx to do the right thing, my workplace is very excited about apex because we will finally be able to get rid of maya, we absolutely hate the fact that we still have to use it in our pipeline and that there no alternative, apex is that alternative and we can't wait to migrate to rig and animate on houdini.
Head of Pipeline @ LightVFX
User Avatar
Member
213 posts
Joined: June 2023
Offline
Jacquesf
that up to your workflow, you could keep complaining about the need to make high level tool, or you could ... you know , start making these high level tool now ?

I've being trying. Actually I've replicated a few less known (not included by default) Blender Rigify component in Houdini, in the "graph editing graphs" way. My complains mostly come from how hard to debug them. (Blender Rigify component is quite unmaintainable itself tho, so it's not about Blender vs Houdini)

I haven't tried to build similar stuff with Python. As I said before, afaik SideFX hasn't made it clear that whether the current geo representation of APEX graph is a public API intended for our use, or an internal implementation detail that is subject to change. That's why I'm hesitate to write Python that directly manipulate them.

Perhaps I'll have a more informed opinion on this subject if I made a Python-based workflow. So far I found "graph editing graphs" quite a headache. Or maybe it's just my blind hate to metaprogramming-like stuff.
Edited by kodra - Dec. 12, 2023 12:26:30
User Avatar
Member
219 posts
Joined: March 2023
Offline
I'm not someone that like visual programming, ue5 blueprint is an heresy to me, but I simply don't really see apex as being programing, for me, it just a new kind of sop network with more datatype.

I haven't done any blender rigging personally, but I'm starting to think differently when using apex, the rig I used to know how to do in maya can be much more simplified by doing them myself on apex using plain matrix deformation, and they actually turn much easier to generate using apex than if I did it in python, because of that 'realtime' compilation, I can see my graph build itself in as I edit the node.

this is the desktop I made myself :


the top level apex graph is my rig building network, and the bottom left graph is the result of that graph.
I have several node in the sop that lets me see the 'output' of my generation graph as either : part of the entire character rig, only the module I'm building, or only a subsection of the rig graph i'm building.

I also have custom apex subgraph that automatically output the result of a node as geometry in the final rig, so I can easily debug what data I have at any stage of my graph.

this is what I mean by building your own workflow, at this point, I have no problem knowing what part of my generation graph build what, and easily figure out any issues as they happen, any change I do in the generation graph is instantly represented on the final rig.

when I say apex is FAST at generating your rig, here an demo of how fast it really is :
I can enable/disable the full rig compilation when I need to work on the module itself, or when it part of the entire rig, and you can see it take no time to update every node.
Image Not Found
(See attached video)
Edited by Jacquesf - Dec. 12, 2023 11:38:15

Attachments:
007514_houdini_9qR37XuoJv_2023-12-12_17-32-26.png (647.2 KB)
007516_houdini_Lt3UEibf3Z_2023-12-12_17-36-10.webm (3.7 MB)

Head of Pipeline @ LightVFX
User Avatar
Member
213 posts
Joined: June 2023
Offline
Thank for sharing your experience. It's definitely much faster than my case, and I'll dive into it later.

IIRC I copied & pasted Lucha's spline component (while I technically don't need it). The other rig components I use are either built-in autorig or quite simple graphs I made.
User Avatar
Member
7760 posts
Joined: July 2005
Online
I go away on vacation and I miss out on the lively discussion.

kodra
If SideFX could be more clear like "how an APEX graph is stored as geometry is not an internal implementation detail, but a public API that is intended for users to manipulate directly. The whole spec will be documented once APEX is out of Beta."

That is correct. This is pretty much how all of Houdini SOPs works because we want studios to be able to add their own SOP nodes that interop with native SOP nodes. So basically anything we output to geometry is effectively a public API. We reserve the right to make changes to this public API still of course but we're very cognizant that once we're out of beta, it will be very difficult to do so.

Jacquesf
there is a few 'hidden' debugging tool that tell that it possible to get all the state of an apex graph as it being worked on, so I have no doubt we'll be able to see in realtime what an apex graph do as you build it (and if they don't, I'll do it myself).

Yes, this is something we need to revisit. Mind you, things are pretty easy to check as you go with the viewport state on each autorig component SOP.

If you have just an APEX Invoke Graph SOP, then the steps to try out the APEX Debug viewport state prototype are:
- Display and select the APEX Invoke Graph SOP
- Set its "Geometry Output Type" parameter to "Debug Graph" and enable "Debug Evaluation"
- From a Viewer State Browser pane, right-click on "APEX Debug" and choose Enter to invoke the debug state.
- Click around on some nodes (points) in the viewport. Notice how you can see the geometry outputs for them. Float values are shown in the HUD in the upper-right corner.
Edited by edward - Dec. 15, 2023 18:05:42
User Avatar
Member
219 posts
Joined: March 2023
Offline
edward
If you have just an APEX Invoke Graph SOP, then the steps to try out the APEX Debug viewport state prototype are:

Thanks for the guide edward, I had a feeling this is how it was intended to be used, I did try some of these step using the APEX DEBUG state and clicking each point on the viewport didn't displayed any of the geometry, but I might have missed a step.

one idea I had to make debugging easier would be to "link" the active stash/edit graph panel that currently being worked on with a remote invoke node that 'use' the graph, so the panel where you edit the graph become at the same time a remote debugger.
In fact, I think even tho apex is a 2 step process where you edit the graph in one part, and execute that graph on the second path, you should get a purposely designed UI that both display the graph you're editing, along side that same graph being 'invoked' (either remotely or via any other mean possible), AND the result of that graph if it purpose is to generate another graph (like a rig component)
such panel would be capable of giving us feedback about which node from the generated graph was generated by which node in the user edited graph, as well as displaying any information about geometry, value going through each plug (you could display the geometry using a floating scene viewer as it even a feature of sop), etc.

here a little mockup of the idea :
Edited by Jacquesf - Dec. 16, 2023 08:01:28

Attachments:
007527_houdini_j9zoHJw1L4_2023-12-16_13-58-31.png (826.1 KB)

Head of Pipeline @ LightVFX
User Avatar
Member
7760 posts
Joined: July 2005
Online
Jacquesf
one idea I had to make debugging easier would be to "link" the active stash/edit graph panel that currently being worked on with a remote invoke node that 'use' the graph, so the panel where you edit the graph become at the same time a remote debugger.

Yeah, that's a good idea. It needs the APEX Network View to advance some more for something like this.

Please log so that we don't forget about this.
Edited by edward - Dec. 16, 2023 13:37:43
User Avatar
Member
219 posts
Joined: March 2023
Offline
Please log so that we don't forget about this.

Done under reference #133765
Edited by Jacquesf - Dec. 16, 2023 15:09:10
Head of Pipeline @ LightVFX
User Avatar
Member
918 posts
Joined: March 2014
Offline
I've been digging into APEX the past few days, and I am struggling in all sorts of places. This one got me thinking…

Jacquesf
seeing it as 'visual coding' is a mistake

I can see your point, yet I cannot find any good examples of producing a graph with code. The page [www.sidefx.com] on APEX in the docs, even show visually building the graphs in the APEX Network view for the simple examples.

I really would like to start building graphs, but even today I failed getting sop::blend shapes::2.0 to work, because the node has to be built with a dict passed to it.

Are there examples of generating graphs with code?

Any help is much appreciated.
Edited by Andy_23 - Dec. 20, 2023 14:10:07
User Avatar
Member
918 posts
Joined: March 2014
Offline
One other thing…

While looking at existing graphs, I can see some outputs are __output__ while others are __binding__
Can someone speak to the difference? Because I cannot create bindings in the APEX Network view.

Thanks
Edited by Andy_23 - Dec. 20, 2023 14:19:11
User Avatar
Member
219 posts
Joined: March 2023
Offline
Andy_23
One other thing…

While looking at existing graphs, I can see some outputs are __output__ while others are __binding__
Can someone speak to the difference? Because I cannot create bindings in the APEX Network view.

Thanks

'binding' is in vop, you're probably looking at vop graph which translate to vex.
Edited by Jacquesf - Dec. 20, 2023 14:27:30
Head of Pipeline @ LightVFX
User Avatar
Member
8622 posts
Joined: July 2007
Online
I see it also in some graphs used instead of __output__, but I guess it's likely that __binding__ is just an old name for __output__ callback, so it may be hidden now
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
918 posts
Joined: March 2014
Offline
Jacquesf
'binding' is in vop, you're probably looking at vop graph which translate to vex.

By that, do you mean this graph was created through VOPs/VEX? It surely is an APEX graph.

Attachments:
binding.jpg (91.4 KB)

User Avatar
Member
918 posts
Joined: March 2014
Offline
tamte
I see it also in some graphs used instead of __output__, but I guess it's likely that __binding__ is just an old name for __output__ callback, so it may be hidden now

I had troubles with the autorig component, it would only execute the second input graph, if the output callback was __binding__.
User Avatar
Member
219 posts
Joined: March 2023
Offline
Ho nevermind then, __binding__ is simply a deprecated node for output, you can use a regular subnet output instead when you see it.
Edited by Jacquesf - Dec. 20, 2023 14:44:06
Head of Pipeline @ LightVFX
  • Quick Links