Temporary variables in VEX Help

Recommended Posts

Hi I'm new to this wrangle node programming, I've been busting my head over why this doesn't work for three days, it's so simple therefor i must be missing out on some general vex concepts.
If anyone can please point me in the right direction that would be greatly appritiated.

I have a bunch of points on a grid and their moving up and down via noise.

I am trying to set up a point attribute that has a value of 1 when a point if moving up (positivly in the Y axis) and a value of 0 when a point is moving down (negativly in the Y axis).

This attribute is called Direction, I'm computing the logic on temporary VEX variables and then writing them out to the attributes. Here's how it looks like :

// 0 is going down, 1 is going up, -1 means the point has no direction

// on the first frame they have no direction so the points just take their current heights so they can use them for comparison on the second and every other frame

int temporary_Direction;
float temporary_Previous_Frame_Height;

if(@Frame == 1)
{
temporary_Direction = -1;
temporary_Previous_Frame_Height = @P.y;
}
else
{

temporary_Direction = @Direction;  // ------------> this is where the problem is  (this is here so that the temporary variable get's the value of the currently proccesing point every frame)
temporary_Previous_Frame_Height = @P.y;

if(temporary_Direction == -1)       // If the point has no direction
{
if(temporary_Previous_Frame_Height < v@P.y)     // If it's going up
{
temporary_Direction = 1;
temporary_Previous_Frame_Height = v@P.y;
}

if(temporary_Previous_Frame_Height > v@P.y)      // If it's going down
{
temporary_Direction = 0;
temporary_Previous_Frame_Height = v@P.y;
}
}
}

// Out_Values
i@Direction = temporary_Direction;
f@Previous_Frame_Height = temporary_Previous_Frame_Height;
// Out_Values

The problem here seems to be when I declare "temporary_Direction = @Direction", for some reason on the second frame when I read @Direction the value wich is given to temporary_Direction is 0 instead of -1 wich was given to every @Direction on the first frame. Temporary_Previous_Frame_Height updates just fine but temporary_Direction doesnt. Also writing "if(temporary_Direction == -1)" doesnt seem to work either.

Is my thought process even slightly right here, what am i doing wrong, are temporary variables created in vex something that exist globally and in order to use them per point we need to read each point's values or are temporary variables something that exist for every point. Also why do i have to give values to all attributes every single frame or else they will reset to 0 (hense the Out_Values section).

//////////////////////////// Update

Thank you everyone for replying. I've tried out the time shift sop and it work's fine now( I dont even need the Previous_Frame_Height attribute anymore). I've updated the main post with the original hip file and the one with the time shift sop.

Learning about the time shift sop is great, but i would still like to improve my thought process on writing code. It would be greatly appritiated if someone can take a look at the original hip file and possibly shed some light on the problem. I've added notes inside the original hip file for clarity.

Any help would be appritiated

Edited by StRaToX

Share on other sites

I've only quickly scan-read your code but first thing I'd try would be to fix the typos - you've spelled temporary with an 'i', ie 'temporari' in a couple of lines

Share on other sites

That was just me misspelling it in this topic, corrected

Edited by StRaToX

Share on other sites

OK,  I thought it probably was but then I guessed you would have copy / pasted it.

I don't have enough time right now to dig very deep but it looks like in this line -

temporary_Direction = @Direction;

you're setting temporary_Direction to zero as you're initialising @Direction in the same line, so the next block of code will never execute as it never equals -1

*edit

I think a much easier way to approach this would be to wire a timeshift SOP into the second input to give you your previous frame, then query the difference in @P.y between the 2 inputs. Or else you could put down a trail SOP with compute velocity set then check the result of

dot(normalize(v@v), {0,1,0})

Edited by j00ey

Share on other sites

Are you running this in a solver of some sort? It probably won't work like you want to if you're just in sops.

Share on other sites

If you could post the scene, so we can see the whole setup,  it might be easier to help. At first glance this shouldn't be complicated.

• 1

Share on other sites

Thank you everyone for replying. I've tried out the time shift sop and it work's fine now( I dont even need the Previous_Frame_Height attribute anymore). I've updated the main post with the original hip file and the one with the time shift sop.

Learning about the time shift sop is great, but i would still like to improve my thought process on writing code. It would be greatly appritiated if someone can take a look at the original hip file and possibly shed some light on the problem. I've added notes inside the original hip file for clarity.

Edited by StRaToX

Share on other sites
`i@rising = @P.y > @opinput1_P.y;`

Time-shifting is a best solution. Wrangle modifies input. Storing something on first frame to retrieve it later will not work. You have to introduce time difference to compare with. All mentioned Time Shift, Trail and Solver methods will work. The original code is not correct assuming the attribute values will be stored on geometry for later use.

rising.hipnc

Edited by f1480187

Share on other sites

I suppose you run into a trap the same way I did it the first time.

The wrangle sop does not keep any informations between frames. The whole input is calculated from the beginning of the chain for every frame. You have tried to save the value at frame 1 and then reuse it later. This only works if the wrangle nodes saves any information between frames what is not the case.

If you want to manipulate some attribute over time, you need a sop solver. Or if it is a static time difference the already known timeShift works fine.

Share on other sites

Ok, that explains allot.
f1480187 demonstrated that with the solver node from the rising file. I'll have to look into the sop solver and solvers in general. So am i correct in saying I will be able to acess value's from any time step and frame inside a solver. Should i just recreate my idea inside a solver ? Well i'm sure it's not as simple i'll look into it some more later.

Edited by StRaToX

Share on other sites

You can't aceess values from any time step inside a sop solver, it only keeps the previous one. You can see it if you dive into the solver, the first node is named "prev_frame". But of course you can save several values in special attributes. But to be clear: Only attributes which can be accessed via "@" are kept beween the time steps, not any local variable you are creating. So if you need some temp variables, create them as attributes before entering the solver and delete them after leaving the solver node.

Share on other sites

If you need to store an attribute for every frame you could use an array and append the appropriate value to it on each timestep then you can retrieve those values by retrieving the correct element.

Share on other sites

That that mean VEX arrays don't reset when houdini cooks a new frame ?

Share on other sites

No sorry, I meant in a solver, and as haggi said, you still need to make it an attribute with the @syntax as well, I just meant that with an array you can store a whole list of values, rather than just the previous frame (or time step).

Share on other sites

when I declare an array like this
int Glitched_Group[] = array();

and then use
push(Glitched_Group, @ptnum);
when i print out the array it just prints 1 for the first element and 0 for all others

also how will i go about transfering this array to another wrangle node

Share on other sites

Can you post an example file? It's easier to see what's going wrong that way.

As far as I can see though, using @ptnum like that only really makes sense in a point wrangle - but that's going to give you an array per point with only one item in it, which is presumably not what you want. I've made an example scene that hopefully might help.

Use the geometry spreadsheet to see what's going on, printing things to the console isn't usually necessary when you're debugging something like this.

I'm no VEX expert so someone else might have better ideas...

array_odforce.hiplc

Share on other sites

Thank you j00ey, now i can finally create a detail array attribute and was able to progress a bit.

Now i'm stuck at trying to make the array carry on through frames. Currently i am trying to create a for loop that will do the calculations for all previous frames, if i try out creating the detail array inside a solver even though it gets created at the end of the tree will it persist from the prev_frame node to the next frame ?

Share on other sites

The output of a solver SOP on frame X is what comes into the prev_frame on frame X+1.

It's difficult to understand exactly what you're trying to do without an example file. If you post one I'll try and have a look.

Share on other sites

Here's the hip file. I've explained inside what i'm trying to accomplish and also explained via comments every step of the point wrangles code

Pls_help.hip

Edited by StRaToX

Share on other sites

Only just got round to having a look at this just now.

If I look in my console, I'm not getting all the y values as zero - this is the last five lines :

prev frame value: {10.5,0.0972875,14.7}, ptnum: 836
prev frame value: {11.55,0.144352,14.7}, ptnum: 837
prev frame value: {12.6,-0.651412,14.7}, ptnum: 838
prev frame value: {13.65,-0.626343,14.7}, ptnum: 839
prev frame value: {14.7,-0.0624275,14.7}, ptnum: 840

That looks like it is getting the values corectly doesn't it?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account