Snippets versus Inline Code

   9960   4   2
User Avatar
Member
45 posts
Joined: March 2010
Offline
Hello!

What are the main differences between the Snippet and Inline Code VEX nodes, and when we should choose one over the other? Is it merely a matter of convenience, or are there functional differences?
(Apart from the whole expression expansion business - eg, using “$” for temp variables)

Also, sidebar question, is there any possible way to access and iterate over edge groups in VFL?
User Avatar
Staff
2540 posts
Joined: July 2005
Offline
As always the answer mostly lies in inspecting the VEX code output.

Implementation within the VEX code is quite different but give you essentially the same result.

The In-line VOP directly injects the vex code in to the body of the VEX code.

The Snippet VOP implements your code as a function and then calls that function within the body of the VEX code. It's interesting to see how the code is generated from the snippet VOP syntax for declaring exposed variables.

Again RMB on any VOP or the VOP SOP containing the VOPs and choose the “view vex code” option.
There's at least one school like the old school!
User Avatar
Member
45 posts
Joined: March 2010
Offline
Very cool. As always, I appreciate your insight, Jeff, that clarified things for me. I was more curious about the differences in the design choices behind, and practical applications of, Snippets vs Inline Code - but your summary and gentle reminder to just look at the generated code answered a lot of questions.

It seems that Snippets are designed to provide a convenient means for inlining light-weight VEX directly in higher-level contexts, while providing @OpInput* bindings that point directly to the various inputs of the wrangle node.

(And by light-weight, I mean, because the Code Snippet parameter is injected into the VFL code as its own function, you can't use a Wrangle directly to define other functions or include libraries (inline), like one would be able to with the Inline Code vop; but you CAN define your functions in an external library, and specify the headers in the Include Files parameter in the underlying Snippet vop, which causes the appropriate #include lines to be dynamically generated right above the Snippet's ad-hoc function definition in the injected VFL code. That's very slick.)

Another difference (unless I'm mistaken) is, Wrangles / Snippets are only concerned with returning attributes bound to the @OpInput1 stream, while the Inline Code node is more suited for directing its output to other VOPs. Is that fair to say?

So, I guess to answer my original question, the Inline Code vop is more suited for heavy lifting - I could define functions or structs and so forth here, should I be so bold; but variables have to be managed much more carefully. On the other hand, Snippets and Wrangles are quick-n-dirty methods for inlining code as more self-contained, one-off tricks. I guess you could say the difference is akin to sleight of hand versus setting up an entire gimmick.

I still don't totally understand how or where the OpInput* variables, or any of the other pre-defined attributes are declared. OpInput1, for instance, appears to be implicitly bound to “opinput:0”, according to the print function - not that I'd ever want to override that or anything. Are these just global variables that “come for free”, as defined internally by VOP context types themselves?


And - last question - POP Wrangles. I couldn't help but notice that they don't exist. It's easy enough to create a digital asset, promoting the multi-line string parameter from a Snippet, but I'm wondering if this isn't provided because it might not work as it does with other contexts? Are there particular limitations to using Snippets in VOP POPs?


Thanks for your time!
User Avatar
Staff
2540 posts
Joined: July 2005
Offline
zachlewis
It seems that Snippets are designed to provide a convenient means for inlining light-weight VEX directly in higher-level contexts, while providing @OpInput* bindings that point directly to the various inputs of the wrangle node.

(And by light-weight, I mean, because the Code Snippet parameter is injected into the VFL code as its own function, you can't use a Wrangle directly to define other functions or include libraries (inline), like one would be able to with the Inline Code vop; but you CAN define your functions in an external library, and specify the headers in the Include Files parameter in the underlying Snippet vop, which causes the appropriate #include lines to be dynamically generated right above the Snippet's ad-hoc function definition in the injected VFL code. That's very slick.)
That's why I referred you to the code. Yes much of this was added in H12.5 as our continual improvement to VEX and VOPs.

Wrangle type operators were added to allow you access geometry in DOPs so that you can type expressions at the top DOP level and not have to constantly edit VOP networks or use In-Line VOPs. It was so incredibly handy that we now use Snippet VOPs all over the place. Spread like wildfire.
We also ported most all related hscript expressions over to VEX as well. I use ch() vex functions all the time to put quick interfaces on top of wrangle operators.
Another difference (unless I'm mistaken) is, Wrangles / Snippets are only concerned with returning attributes bound to the @OpInput1 stream, while the Inline Code node is more suited for directing its output to other VOPs. Is that fair to say?
Yes that is a fair assessment. In-Lines are just that: inject in-line code in to a VOP network as a quick way to shove a function in there that isn't supported by a VOP.

Having said that, if we don't have a VOP for a commonly used function, please submit that as a Bug. We shouldn't be using in-line operators for commonly used functionality.
So, I guess to answer my original question, the Inline Code vop is more suited for heavy lifting - I could define functions or structs and so forth here, should I be so bold; but variables have to be managed much more carefully. On the other hand, Snippets and Wrangles are quick-n-dirty methods for inlining code as more self-contained, one-off tricks. I guess you could say the difference is akin to sleight of hand versus setting up an entire gimmick.
Funny. I see In-Line VOPs as the hackers way of shoving a vex function in there. To be honest, I find it just as fast to create a new VOP type and write my code as a first class asset. Make it re-usable.

Wrangle operators simply allow you to modify geometry using vex at the SOP level quick and dirty like. Many a power user would not be happy if we implemented more things in VEX/VOPs as you get threading for free and not give them “hero healing powers” to write a magical quick and dirty expression while people are hovering over them in approvals.

That's the real reason why Wrangle nodes and the Snippet VOP exist.
I still don't totally understand how or where the OpInput* variables, or any of the other pre-defined attributes are declared. OpInput1, for instance, appears to be implicitly bound to “opinput:0”, according to the print function - not that I'd ever want to override that or anything. Are these just global variables that “come for free”, as defined internally by VOP context types themselves?
Exactly, and mainly for Volumes.
We are constantly using the Volume type VOPs with their file dependencies but as we know, in SOPs you can use the op: syntax to fetch the geometry within the Houdini session.

We just added a first-class method of accessing various inputs for processing volume data all inside the VOP network easily. No more op: for importing and processing volumes.
And - last question - POP Wrangles. I couldn't help but notice that they don't exist. It's easy enough to create a digital asset, promoting the multi-line string parameter from a Snippet, but I'm wondering if this isn't provided because it might not work as it does with other contexts? Are there particular limitations to using Snippets in VOP POPs?
Houdini12.5 texport:

/ -> cd /obj
/obj -> opadd dopnet
/obj -> cd dopnet1
/obj/dopnet1 -> opadd popforce

Check enable Use Local Expressions.
It is for this very node that the Snippet VOP and wrangle workflow was created…
There's at least one school like the old school!
User Avatar
Member
45 posts
Joined: March 2010
Offline
We also ported most all related hscript expressions over to VEX as well. I use ch() vex functions all the time to put quick interfaces on top of wrangle operators.

Yes! When I saw that you could do this in Ari's Wrangle workshop video, it was really illuminating. One of my favorite things about Wrangles is that they fold really nicely into presets - they're so wonderfully self-contained. Because both the parameter interface and the values (eg, code) are saved into the gallery, they can almost serve as a poor-man's digital asset. I've found myself slowly building a diverse wrangle library almost by accident, just as a function of wanting to save my code for future reference, when I'm in a bind. Pun totally intended.

(my only gripe about the ch() workflow is that pasting relative references into the multi-line snippet field replaces all your code, like it does with other parameter types; but that's hardly a showstopper )

We just added a first-class method of accessing various inputs for processing volume data all inside the VOP network easily. No more op: for importing and processing volumes.

That's great news – the op: business is always a tad bit more of a mental exercise than I'd like it to be, when all I wanna do is make my volumes all noisy and pyroclasticy and stuff.


/obj/dopnet1 -> opadd popforce

It is for this very node that the Snippet VOP and wrangle workflow was created…

Oh boy. This is going to be a lot of fun to mess with. I guess the first step is to figure out what the hell kind of data its looking for, and move on from there! It looks like you guys have a lot of hidden pop-dop-dealies… real curious to hear what you guys have up your sleeves…

Anyway, thanks again for your clarifications and for steering me toward all sorts of stuff to play with!
  • Quick Links