Where is the VEX syntax reference?

   1561   11   0
User Avatar
Member
311 posts
Joined: Oct. 2016
Offline
Hi there,

"VEX is loosely based on the C language, but takes ideas from C++ as well as the RenderMan shading language." (Houdini 19.5 [www.sidefx.com])

when coming from en experience with Python, BASH and JavaScript using VEX beyond the basic attribute manipulation tasks can become an experience of trial-and-error.

I've been searching around the net and so far has not seen a proper syntax overview of the language. There are a bunch of examples, especially videos, showcasing time consuming cases that are merely fragments of how VEX can be used.

The situation has become time consuming for basic things like making functions, and using arguments, and having to discover what is supported and what is not. The editors or the language does not have a built in debugger like Python has, so the need for it is greater than for Python.

So my question is this?

Where is the syntax overview of the language, or is there none and if so how come?

Where are the rules for what works and what not?

And please, don't point me to any list of 100+ vimeo or yt videos showcasing a multitude of specific projects with fragments of VEX syntax and semantics.

Another related question: If one is an expert in C syntax, will this be nearly 100% transferable to VEX? If not, again, where is the syntax and rules reference?

When developing with Python finding such answers is a matter of seconds usually, because there is so much documentation (in text) available regarding the syntax and rules.
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
User Avatar
Member
8577 posts
Joined: July 2007
Offline
it's here:
SWest
...(Houdini 19.5 [www.sidefx.com]) ...

just follow any of the subtopics to learn more about the syntax
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
311 posts
Joined: Oct. 2016
Offline
tamte
it's here:
SWest
...(Houdini 19.5 [www.sidefx.com]) ...

just follow any of the subtopics to learn more about the syntax

Just... yeah, it is just weeks of digging.

Been there and done that, but it is not enough. And my experience is that it is much like a labyrinth.

This [www.sidefx.com] about functions is not enough.

So, basically I'm referred to making my own reference guide. I've been using the search tools and usually have to search quite a lot to find the answers that I'm looking for. Also, the experience is basically learning by trial-and-error to find out what simply will not run.

I'm not coming from a C/C++ background and have only done RSL on a basic (occasionally advanced) level.

Edit: Simply having a lot of well organized and short examples in text, also with different complex situations, could be rather helpful. At the moment the docs seem to assume prior knowledge in using C or C++ it seems. Meanwhile I don't think having that would be enough anyway, although it would simplify things somewhat.

With Python I can focus on logic (algorithms) because there are so many examples that can be used to solve the syntax questions. However, this approach is not possible with VEX using the given tools available.

You can always add the "magic" ingredient called time, by simply reading or looking through tons if irrelevant materials. If you replace the word time with a cost per hour, then it become too much, and the method is ineffective. The trial-and-error method is also a negative experience.

Having many short examples, especially from function or object oriented programming (or both) could make using VEX more accessible.

Python has a much larger user base than VEX, and I see this as a problem (making books is probably not feasible financially), however learning materials don’t need to be so challenging.

For an excellent, broad and well covering video series of VEX with PDF for quick reference I’d happily pay $$$ for a copy because my time is worrh more. However, I don’t want those specific cases offered.

For now making my own reference library (with usable examples) seem to be at least a working solution, but this will take too much of my time (that I don’t have ATM).

I’m not saying the docs are bad, however they are assuming prior knowledge and have too few examples for my request for efficient methods.

If anyone want something in this regard, here’s something official:

VEX video guide [www.sidefx.com]
Edited by SWest - Oct. 5, 2023 07:26:55
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
User Avatar
Member
8577 posts
Joined: July 2007
Offline
you can also refer to Matt's CGWiki for some quide and examples
https://www.tokeru.com/cgwiki/JoyOfVex [www.tokeru.com]
https://www.tokeru.com/cgwiki/HoudiniVex [www.tokeru.com]
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
311 posts
Joined: Oct. 2016
Offline
tamte
you can also refer to Matt's CGWiki for some quide and examples
https://www.tokeru.com/cgwiki/JoyOfVex [www.tokeru.com]
https://www.tokeru.com/cgwiki/HoudiniVex [www.tokeru.com]

Thanks, I did many of those already.

Also I found some examples for manipulating cregions from that site.

The VEX not scary guys has some documents that you can get for a small cost. Maybe I’ll try to get some sneak peak about that somehow.

Anyway, now I started a long journey documenting VEX the way I like. It will take forever, but I’ll learn along. Unfortunately I’ve done many things but not been taking notes (except Joy of VEX and a few things). That was a mistake. Anyway, the long journey it is.

Cheers!

There is a debugger in the Alt+E editor.
Edited by SWest - Oct. 5, 2023 10:56:34
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
SWest
With Python I can focus on logic (algorithms) because there are so many examples that can be used to solve the syntax questions. However, this approach is not possible with VEX using the given tools available.

From my experience, it is the opposite - Vex is so easy in Houdini while Python in Houdini is like you say:

SWest
And my experience is that it is much like a labyrinth.

[
SWest
With Python I can focus on logic (algorithms) because there are so many examples that can be used to solve the syntax questions. However, this approach is not possible with VEX using the given tools available.

For me it's much easier to focus on logic with VEX(which is why I like it) because the syntax is 'strict' and less ambiguous(there are elements of Python than make it more flexible - but I find you have to remember more things as a result - which is why it's easier for me to focus on the logic and my own algorithms in VEX.

SWest
Having many short examples, especially from function or object oriented programming (or both) could make using VEX more accessible.
Short examples of what? What do you feel is missing?
The docs in regards to describing what a function does, yes is some instances could use some work - but in my mind more for clarification - not examples to show application. The reason is, a good function means it can be applied to multiple cases and needs. It depends on the person and their needs.
How a function 'works' in Vex has only a few elements that are shared across the board for all vex functions, e.g. you supply arguments, the function either or both returns a value or changes a supplied argument, etc.
The docs describe these basic features of each function.
So what examples does one need? because how one decides to apply those functions together with other functions or their code is up to the person - Their own logic.
Vex also is typically not used in a context where you have to or need to start writting sophisticated and elaborite code where you start using 'structures' and other functions in externally referenced files that begins to resemble OOP. And the the purpose of OOP is not to do it for it's own sake but as a means to accomplish ones goals.
IMO if one needs to start writting code that begins to resemble an OOP 'format' - They are better off to start and dig into the HDK which is using C++ and compile for Houdini there; not with VEX.
I don't feel adding examples to the docs (at least for the functions section) is a good idea. With the continuing addition of new functions, like in the Solaris, plus adding examples would just defeat the purpose of the docs in that it would take longer to navigate to the find a reminder of what a functions input/output is.
The section on syntax as already mentioned by Tamte is all there is to learn about syntax.
Adhering to the syntax just lets the compiler does it's job of converting your logic into something that can be used.
If you feel there is something that is not clear about the syntax of VEX, then why not just post questions in the forum.
IMO vex syntax is simple and 'short' - meaning not much to remember; After which, it's just your logic that remains.
User Avatar
Member
311 posts
Joined: Oct. 2016
Offline
BabaJ
Short examples of what? What do you feel is missing?

There has been a few cases where finding the syntax has been too time consuming. However, as Tamte suggested I did look for examples from which I could extract some syntax. It just seem a bit unexpected to need to use places like tokeru.com for examples.

// a function that deletes a cregion
function string delCreg(string creg_names[]; string creg_to_del; int boneCapture_i[]; float boneCapture_d[])
{
// arguments are references to the actual attributes


// here (in the function) this will still work because the real array is referenced
// here a cregion is deleted
pop( boneCapture_i, index_to_del );
pop( boneCapture_d, index_to_del );

[...]

// calling the function (working example)
delCreg(creg_names, creg_to_del, @boneCapture_index, @boneCapture_data);



// note: placing @boneCapture_index as an argument for the above function does not seem to work. 
function string delCreg(string creg_names[]; string creg_to_del; int @boneCapture_index[]; float boneCapture_d[])
function string delCreg(string creg_names[]; string creg_to_del; @boneCapture_index; float boneCapture_d[])



// this is the example from the docs
function int test(int a, b; string c) {

Coming from a Python background having to add those square brackets I had to figure out.

I had long time trouble with passing an attribute as argument to my function. This [www.sidefx.com] note in the docs gave me a hint however: "As in RenderMan Shading Language, parameters to user functions are always passed by reference, so modifications in a user function affect the variable the function was called with. "

So I simply created a new (local) variable, e.g. boneCapture_i, and sending the actual attribute data to it still worked. It would change the attribute because it is not a local variable only, it is a reference to the real thing.

Another example could be, imagine you want your function to return an array, how would to do that? Coming from a Python background this was quite challenging.

Furthermore, since I have many years of experience and a little formal education doing Python this has been quite easy with Houdini. Sure, it was a bit tricky to get into the object oriented nature (I've mostly been doing functional programming, and I had a basic understanding for OO anyway), however, it is consistently designed and quite impressively done actually. Working with Python in Houdini has been like a walk in the park compared to with other software (none mentioned). Somehow it is very logically designed, and I have found it to be very compatible with my way of thinking about it. However, I've used sources like Stackoverflow a lot and my own snippets. There is also the built in documentation as well, unfortunately I've been having to do screen grabs of that pop-up docs that disappears as soon as you move your mouse away (if you know what I mean?). Some parts of the HOM is really challenging though, for example when you can not point on a parm to get the name, or for things like the Scene Viewer which you probably need examples or really understand the docs, and some luck, to use it. For example, how would you press "enter" on a node to enter its default state? That was tricky to figure out with Python.

Anyway, these are just some examples. I hope you understand, and I'm sorry for the language errors (I'm in a hurry).
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
SWest
// note: placing @boneCapture_index as an argument for the above function does not seem to work.
function string delCreg(string creg_names; string creg_to_del; int @boneCapture_index; float boneCapture_d)
function string delCreg(string creg_names; string creg_to_del; @boneCapture_index; float boneCapture_d)

In your second function line you have not declared what the @boneCapture_index is suppose to be but at the same time in both lines you are declaring that they are going to be attributes. You don't do that for declarations, you just declare the 'type'.
That means when it comes to actually using the function, if the argument is declared for example as an int - you can use either a locally declared int or an attribue that is also an int.

SWest
// this is the example from the docs
function int test(int a, b; string c) {

Here, although it may appear the same, this is a description of what you need to know for the function, i.e. what the arguments are going to be, what it returns, etc.

It is not a declaration like what you have for delCreg.

One is for you the other is for the compiler.

I wanted to say earlier, I don't think it's wrong for you to want to have a more detailed documentation to help you get familiar with the syntax which will differ from something you are already familiar with like Python.
But I think that imo should be kept away from documentation and put in the catagory of tutorials.

I can see why since my case was the opposite - I was familiar with C to some extent but only started with Python when using Houdini.

What I did is simply googled 'how to learn Python' and look for simple examples which I could take over into Houdini.
This helped because I was able to see the difference between what is 'pure' Python syntax and what was Houdini specific.

For example with vex - someone could be well versed in c/c++ but they still have to learn say what a point wrangle does with the data in point mode (parallel processing of points) - the ins and outs of working with attributes vs. localy declared variables, etc.
I think if you did something similar and do a little bit of c or similar language outside of Houdini...you might be able to get a better sense of vex, seeing the similarities and difference due to context(wrangling data in a Houdini scene).

SWest
Another example could be, imagine you want your function to return an array, how would to do that? Coming from a Python background this was quite challenging.

I would declare I'm returning an array with my function and within the function and using a loop and the function push() create the array.
Edited by BabaJ - Oct. 5, 2023 18:57:28
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
I just came across this code in another thread and not to discount anything you said;
I thought you might, if you happen to read this, might appreciate the 'same frustration' for lack of a better word,
of someone like myself who has a bit of c background and took to vex easily, but not python.
Because I had no need to know that the thread was about, I didn't ask for an explanation.
But just to give you an idea, for explanations sake...

So I'm looking at this code and wondering how the heck is this working,
the 'declared' function ...def foo(..... has only a return,
I couldn't figure out what it's returning and it seems ambiguous to how he is using it in
hou.Node.moveToGoodPosition = foo

Foo doesn't even have brackets or any arguments given it.(at first glance I don't know I'm dealing with a function),
but if the function is only a 'return' what is it passing on the hou.Node.moveToGoodPosition?

So I looked at a Python 'syntax' site, and it appears such a function written would return a 'none'.
So what is the 'value' of none that hou.Node.moveToGoodPosition is using?

integer 0, string '0', is it the comparable 'null' in c?

I would have to go to HOM and lookup moveToGoodPosition to find out what it 'takes' for 'inputs'.
(and/or do a internet search of Python and find out what 'none' is, does Python treat what 'none' is differently under different circumstances, etc.)

But for someone already familiar with Python I'm sure they are thinking, this is easy to see what is going on.

This is one of the angsts I have with Python in general, you have to remember more things about how the code could be written.
I find it harder to understand at times from the syntax alone(which I find much easier in vex/c type languages - strict).

So I thought I would just give some attempted comparable example;
Again, not to dismiss your desire for more documentation on syntax(examples) - but to highlight what I think is difference between documentation examples and examples to help one learn the syntax of a programming language.



LuSkar
jerry7
You can disable MoveToGoodPosition():


import hou
def foo(obj,relative_to_inputs=True, move_inputs=True, move_outputs=True, move_unconnected=True):
return

hou.session.__bak_moveToGoodPosition = hou.Node.moveToGoodPosition
hou.Node.moveToGoodPosition = foo


If you want to restore:

import hou
hou.Node.moveToGoodPosition = hou.session.__bak_moveToGoodPosition
Edited by BabaJ - Oct. 11, 2023 08:59:18
User Avatar
Member
311 posts
Joined: Oct. 2016
Offline
for someone already familiar with Python


There’s the key. We don’t learn objectively. What we see and interpret is related to what we have learnt so far.

Vygotskij’s concept is that we are sensitive (meaning responsive) to certain information based on what we learnt so far. The learnt tools (mening language, representations and symbols) will be used (by the learner) to interpret new information.

The example you gave I see as a solution to a problem. The fuction can’t be empty.
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
User Avatar
Member
2042 posts
Joined: Sept. 2015
Offline
SWest
The example you gave I see as a solution to a problem. The fuction can’t be empty.

Yes, but in c/vex it's easy for me to know where to look (judging by the syntax alone) to figure out what that value is.
With Python, and lack of experience, I can't tell where to look for such an answer.
User Avatar
Member
311 posts
Joined: Oct. 2016
Offline
This thread has evolved somewhat into a discussion related to syntax between Python and VEX. It is still relevant to the original post, since where we come from will determine how we understand new information.

Here are some comments for those who would like to study a little about Python in Houdini. If you find any mistakes (I'm quite in a hurry and did not sleep well) feel free to point it out. If you have another perspective you are encouraged to share it.

I've mostly been doing functional programming, and just a little OO-programming, but the HOM is very much object oriented. Some times I write "function" when it probably should be called "method", but it looks exactly the same as a function and does the equivalent.

Functional programming is more oriented towards processing data through functions, while object oriented programming is a clever way to organize data and instructions. For snippets a couple of lines, maybe with function, is usually enough. For larger models of code an object oriented approach makes the development process more manageble. It resembles how humans think about objects (while classes are like small mass production factories).

Objects in code are not only like objects in grammar, but are also subjects, i.e. they can do or change things with their methods. At the most core level (CPU) there are instructions and data that interact with very primitive logic such as copy data, compare data, jump to instruction, and math operations etc. So because machine code is too inefficient to manage the languages and their rules are human constructions made by and for humans.

What this leads to is that you are not supposed to guess how grammar (syntax) for a language is designed.

Cheers!

First some points about Python and programming
  • Learning programming is relativaly challenging because it implies several skills. For example first of all understanding how something works in the first place. Then it requires more or less project management abilities about how to go about doing something. Then this has to be explained to the (rather stupid) computer.
  • This also include a lot of problem solving on the way to implementing features. Finally there is the need for documentation, user friendlieness, maybe refactoring and probably some maintainance. Learning syntax is just the tip of the ice berg. However, once these abilities are developed they can be translated to other contexts and languages.
  • AI is NOT the genious of machines, but ONLY the excellence of human collaboration and design when using machines.
  • Python is a quite slow programming language, but works way faster than humans do. So it is popular to use as an interface API. Data scientists often use Python, maybe partially because their salaries are higher than the cost for simply adding more CPU:s.
  • Python is fast to program (for those who know it well) and useful for prototyping.
  • Python is like the glue between the human being and the low level code (C/C++ or equivalent).
  • If something is too slow then it is possible to use Python to call a C/C++ program that optimizes only that part.
  • Python also support multiprocessing, but so does C/C++.
  • Computer Science has two main branches: Information Systems and Computing. "Information Systems" are not focused on low level performance but rather human interaction. The "Computing" branch however is more oriented towards high performance and low-level thinking. There is no conflict about that, just different tools for different purposes.

Here follow some comments about the example code snippet.
  • Probably the most important statement i.e. the plan for the following code. It represents the thinking human behind everything.
  • The alorithm implied is to create a function that does nothing, but does neither produce an error.
  • It also implies a backup of the original functionality.
  • Comments do not explain the underlying code to humans, but the opposite, the code beneath the comment explains the comment to the computer.
You can disable MoveToGoodPosition():

  • import the entire HOM with classes as well as the present objects in the scene definition.
  • Classes will begin with capital letter i.e. "Foo()". Objects generated from them inherit the same name but begin with a lowercase letter i.e. "foo()".
  • Each object generated has methods (like built-in functions).
  • Parms usually use lowercase with underscore this_is_a_parm.
  • The above mentioned approach is consistently used in the HOM (import hou).
  • Classes and objects usually have built in descriptions, i.e. the '''description''' line(s) directly under the first line. This is the pop-up available in the embedded Python Shell and is standard for Python.
import hou

  • Define this method called foo (here it looks identical to a function).
  • Obj is a positional argument that is required, while all other arguments are predefined and have a default data type and value (the value may be overridden but not the type).
  • The arguments are not really needed for this seemingly empty function, but to avoid error messages when the args are sent from various places in the HOM they are used here.
def foo(obj,relative_to_inputs=True, move_inputs=True, move_outputs=True, move_unconnected=True):

  • The following returns nothing, maybe it is a Null or something equivalent.
  • Here it become similar to just a "break" in a loop but that will not work in a function. However simply using a return will satisfy the Python rules for methods (and functions).
return

  • Here hou.session is used, which is defined and stored until you restart Houdini.
  • It is useful when you want to be able to "retrieve" your own Python modules, classes, variables or whatever inside Houdini. So here it is used to store a backup of the original function moveToGoodPosition() in the Class called "Node" (note the beginning letter).
  • The name __bak_moveToGoodPosition is arbitrary.
hou.session.__bak_moveToGoodPosition = hou.Node.moveToGoodPosition

  • Here the method "moveToGoodPosition" inside the Class "Node" is overridden by the function "foo". What this mean is that for each new object node (lowercase letters) that is generated from the "Node" class the method does nothing.
hou.Node.moveToGoodPosition = foo


  • As mentioned, some user support is required by the programming role.
  • On one hand you can not assume that the CPU or language will understand what you are doing (it is stupid in that sence). It helps to imagine that you are defining things in empty space (vacuum) and nothing exist unless you define it.
  • On the other hand it is risky to assume that the intended user understands what you have done.
  • In that perspective the programming role resembles that of the translators, i.e. to translate a plan to the computer, then somehow translate that to the user. Well, this is only part of the story.
If you want to restore:
import hou

  • Here the backup of the function/method moveToGoodPosition in the Class "Node" is stored in the session and can be copied back as in the following line.
  • We usually use versions to prevent the risks of human errors but also for communication within teams and with the target group. The idea of safety measures is very important to avoid loosing motivation (time, value and money) due to lost work.
hou.Node.moveToGoodPosition = hou.session.__bak_moveToGoodPosition
Edited by SWest - Oct. 13, 2023 03:05:31
Interested in character concepts, modeling, rigging, and animation. Related tool dev with Py and VEX.
  • Quick Links