need help with conditional expression

   18369   16   5
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
Hi,

I don't normally post questions, I'm always too busy to wait for an answer and assume it's out there somewhere, but i'm stuck.

I'm simply trying to do a conditional statement in the first field of a point SOP's normal parameter and can't get it to work using Hscript.

i've tried these various syntaxes:

if (1 == 1) then
echo 4
endif

if (1 > 0)
return 4
endif

if 1 > 0 then
return 4
endif

if (1 > 0) {
return 4;
}

i've changed operators and swapped “return” with “echo”. and simply left nothing but the value… nothing seems to work. any examples of how to do a conditional statement in a point SOP parameter would be MUCH appreciated.

Thanks,

-sunyata
Edited by - March 27, 2010 00:01:46
I can see Russia when I surf.
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
why is it that whenever you post a question you then find the answer on your own?

this is working for me on a single line:

if(1>0,4,0)

duh.

python syntax also worked as expected but i didn't want to use functions to capture vars so i'm trying to get hscript to work. still not sure why all the multiline hscript examples didn't work though…
I can see Russia when I surf.
User Avatar
Member
321 posts
Joined: July 2005
Offline
if($F<10,1,0)
In parameters, you have to provide an expression, not hscript script. The expression (type ‘exhelp’ in textport for list of expressions) will evaluate and return a value based on what the expression does. This is not like the Python expressions, which are Python code.
Antoine Durr
Floq FX
antoine@floqfx.com
_________________
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
ah, i think i understand. thanks for answering my newbie question.

so i have to use the hscript functions in the parameters field and cannot just write hscript… but i CAN write standard single/multi line python using custom houdini functions/methods..

so as far as writing a multi line expression with hscript expression functions, is that possible?

how would you do an “elif” for example aside from python?


thanks!
I can see Russia when I surf.
User Avatar
Staff
2540 posts
Joined: July 2005
Offline
hscript expressions are all on a single line. You can use the alt-e to get to the expression editor and introduce carriage returns in your expression string but ultimately it will be one long expression.

There is one other alternative to writing complex functions other than hscript or python in parameter fields and that is to write a custom expression. This is overlooked far too often.

http://www.sidefx.com/docs/houdini10.0/expressions/_custom [sidefx.com]

covers how to write your own custom expression in hscript. I call this language pseudo c and c-shell programming. There is a special loophole too.
Normally when writing a custom expression, you do it and save it in the hip file then reference it. The special case is writing the custom function right in the parm.
You don't need to put in the first line declaring the function name and the arguments. Just dive in and put in your two curly braces and write your function in there:'

{
float true = 1;
float false = 0;

if ( 1==1 ) {
return true;
} else {
return false;
}

}


Just make sure the return type matches the parameter field your custom expression is in. As well, you don't have to declare floating point variables but it is a good habit to do that.

What is also neat is this is compiled for you and runs very fast.

Times past before Python you would first write your expression linking up several hscript expressions. Once it gets too long (for me that would be say 5-6 functions chained together) you can rewrite it as a custom function right in the parameter or write a general purpose expression function following the instructions from the help link above.
When that gets to be 100 to 200 lines long, then bust up in to several expressions.
Writing custom expression functions in parms is also great if you have to rip through a lot of conditionals. Your examples triggered my response to try out custom expressions.
There's at least one school like the old school!
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
Jeff-

That's awesome, thanks for the reply. I think next time I'd opt to use your trick.. it's easier to read

So this is probably an ugly solution to my problem but here is what i was trying to do.

i warp a long twisted noodle using a point SOP to add normals pointing back in z (relative to points local tangency) and warp them with a mountain SOP.. then try to do the same thing in the new x using another point SOP and another mountain SOP.

The trick was getting the new value of x for the normals.


if($PT%2==0,($TX-point(“../mountain_z”,($PT+1),“P”,0)),(point(“../mountain_z”,($PT-1),“P”,0)-$TX)))


it works because i only have 2 rows of points, even points look over at odd and visa versa. I'm sure there is a better way!

Thanks again.

Attachments:
normal_test.png (6.8 KB)

I can see Russia when I surf.
User Avatar
Member
321 posts
Joined: July 2005
Offline
You could also just feed each curve into one input of the point SOP and then into the normal parms place:

$TX2-$TX
$TY2-$TY
$TZ2-$TZ

i.e the normal becomes one aiming at the other. I sometimes also put a sort SOP in between and shift the points on one side by +/- 1 if needed.
Antoine Durr
Floq FX
antoine@floqfx.com
_________________
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
Antoine-

Thanks.. I thought that would be the easy way at first but since the “noodle” here is coming off a creep SOP, I don't have 2 curves to input.. only quad poly objects. I tried using 2 delete SOP's and piping them into a point SOP as you suggested, then attrib transfer. Problem was new prim nums on the normals. Think it may be slower too, not sure?

I tried re-doing with the multi-line trick for readability though, works fine:

normMult is a custom parm.


{
if($PT % 2 == 0){
return ($TX-(point(“../mountain_z”,($PT+1),“P”,0)))*ch(“normMult”);
} else {
return (point(“../mountain_z”,($PT-1),“P”,0)-$TX)*ch(“normMult”);
}
}


Thanks again for the help…. love houdini!

-sunyata

Attachments:
normals_final.png (27.6 KB)

I can see Russia when I surf.
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
anyone tried using & instead of % in Hscript to test for even / odd numbers?

supposed to be faster in python than using modulus.



if (23 & 1) == 1: “odd”
I can see Russia when I surf.
User Avatar
Member
321 posts
Joined: July 2005
Offline
sunyata
normMult is a custom parm.


{
if($PT % 2 == 0){
return ($TX-(point(“../mountain_z”,($PT+1),“P”,0)))*ch(“normMult”);
} else {
return (point(“../mountain_z”,($PT-1),“P”,0)-$TX)*ch(“normMult”);
}
}

In a situation like this, I like to make a pair of point groups, the ‘evens’ and the ‘odds’, and use two point SOPs each with either part A or part B of the above expression. It makes it simpler to tweak, IMO.
Antoine Durr
Floq FX
antoine@floqfx.com
_________________
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
Antoine-

Do you think there is any speed hit doing 2 sets of groups? I see that as calculating modulus twice for all points. maybe not? I'm trying to optimize as much as possible since this is all in a “foreach” SOP and could have many “noodles” in the end.

thanks.

debating testing Hscript against Python for speed and using bitwise & instead of % in python…
I can see Russia when I surf.
User Avatar
Member
321 posts
Joined: July 2005
Offline
sunyata
Antoine-

Do you think there is any speed hit doing 2 sets of groups? I see that as calculating modulus twice for all points. maybe not? I'm trying to optimize as much as possible since this is all in a “foreach” SOP and could have many “noodles” in the end.

thanks.

debating testing Hscript against Python for speed and using bitwise & instead of % in python…
The modulus is cheap, but the point() function is expensive. My approach will most likely run slower as it triples the number of SOPs. Whereas you have a single point SOP, I have at least one group SOP (which can make both groups in one go), and then two point SOPs. I was going for ease of maintenance and tweaking.

In situations like this, I initially don't worry too much about the performance, as speed of iterating with different functions and fleshing out what it's actually supposed to do are more important. It may very well be that even with all your “noddles” that the time is tolerable, so there's little point in hyperoptimizing from the get-go. You may also find that while you need the foreach to create the geomery, you can use a single point SOP to move the points around, which would be much faster.

And finally, if things are just crawling, I pull up the performance monitor (alt-y) and look exactly what is costing so much time in cooking.
Antoine Durr
Floq FX
antoine@floqfx.com
_________________
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
Antoine-

thanks for the alt-y tip.. i'll use that often. unfortunately i'm always obsessed with optimization, it's a disease.

interesting that the point SOP is so much slower than the mountain SOP and the modulus more than doubles the time from the previous generic point SOP that adds $NX $NY $NZ.


17.90 ms /obj/noodles/foreach1/each1 <= foreach iteration

91.90 ms /obj/noodles/foreach1/pointZ <= point adds $NX $NY $NZ

9.19 ms /obj/noodles/foreach1/mountain_z <= warps in z

221.91 ms /obj/noodles/foreach1/pointX <= point w/ % function

17.56 ms /obj/noodles/foreach1/mountain_x <= warps in x


there are going to be lots of instances so it's really good to know.. thanks.
Edited by - March 27, 2010 00:09:13
I can see Russia when I surf.
User Avatar
Member
321 posts
Joined: July 2005
Offline
sunyata
interesting that the point SOP is so much slower than the mountain SOP and the modulus more than doubles the time from the previous generic point SOP that adds $NX $NY $NZ.
It's not necessarily the point SOP itself but the point() functions inside it. They're aiming at another geometry, and getting a *random* point from that geometry. The point SOP at least has the advantage that it's acting serially: start at point number 0, go to point number 1, etc. all the way to the end, but point() doesn't have that advantage. Historically the point() function was dog slow, but it's pretty zippy these days, so much so that we take it for granted.

The mountain SOP just does a for loop on the points, moving each one according to a formula, so it does not do any per-point local variable evaluation.

Also, I don't know what kind of overhead is incurred by placing an entire expression function, curly braces and all, into a parameter. It could be that it has to recompile the expression function on each frame? I have never done it (and would much rather make a standalone .func that I exread) than put a complete expression function in there.
Antoine Durr
Floq FX
antoine@floqfx.com
_________________
User Avatar
Member
14 posts
Joined: Dec. 2008
Offline
Antoine-

Yes, I was aware of that and wondering if the point function would be slow… it seems like it's just accessing a value from a list or tuple, very low overhead per iteration.

The point SOP that just adds default norms is slower than a mountain SOP that is randomly offset per object per frame. Almost 10x actually, but another way to look at that is that the mountain SOP is very fast

I'll check out how to install a .func file and access it, thanks.
I can see Russia when I surf.
User Avatar
Member
321 posts
Joined: July 2005
Offline
sunyata
Antoine-

Yes, I was aware of that and wondering if the point function would be slow… it seems like it's just accessing a value from a list or tuple, very low overhead per iteration.

The point SOP that just adds default norms is slower than a mountain SOP that is randomly offset per object per frame. Almost 10x actually, but another way to look at that is that the mountain SOP is very fast
The point SOP with just about anything will be slower because it's evaluating the local variables on each and every point. So it has to eval the parameter, encounters $NX, has to go find what $NX means, run the callback that sets $N, replace that, continue on its eval of the function. The mountain SOP does not have per-point local variables. It stays in C++ land and just does a for/next loop on the points.
Antoine Durr
Floq FX
antoine@floqfx.com
_________________
User Avatar
Member
208 posts
Joined: Nov. 2010
Offline
sunyata
why is it that whenever you post a question you then find the answer on your own?

Always happens to me. Almost always anyway.
  • Quick Links