Friday 29 September 2017

VOP For Loop usage

The inputs of the VOP For Loop are a bit annoying.
Length - this is the number of loops to be made. It is the i<10 part of the loop.
Index - you don't have to set this unless you need to start with a value other than 0. eg, you want to start the loop with for(i=3;i<............)
The rest is just for any attributes/values you need to use.

connecting points again..


Here're two expanded ways of connecting groups of points together!




The first method relies on you creating an attribute in a preceding point wrangle called "id". This is the value you'll search for, when making connections. The "destination" points go into the first input, the origin points go into the second.

int count = findattribvalcount(1,"point","id",i@id);

for (int i = 0; i < count; i++) {
    int find = findattribval(1,"point","id",i@id,i);
    
    int prim = addprim(0,"polyline");
    
    vector p2 = point(1,"P",find);
    
    int pt = addpoint(0,@ptnum);
    setpointattrib(0,"P",pt,p2);
    
    addvertex(0,prim,@ptnum);
    addvertex(0,prim,pt);
}


LINE BY LINE

int count = findattribvalcount(1,"point","id",i@id);
//count number of points that have the "id" value
for (int i = 0; i < count; i++) {
//start for loop, for the number of points it has found
    int find = findattribval(1,"point","id",i@id,i);
    //get point number for point that has the id value. The last i is the index of the for loop.
    int prim = addprim(0,"polyline");
    //add primitive, of polyline type
    vector p2 = point(1,"P",find);
   //create position vector based on point number found 
    int pt = addpoint(0,@ptnum);
//create point at the position of current point
    setpointattrib(0,"P",pt,p2);
    //set position of just created point to the vector created
    addvertex(0,prim,@ptnum);
//add vertex to the primitive at current point position
    addvertex(0,prim,pt);
//add vertex to the primitive at found point position
}





This method doesn't need the "id" value, but just grabs the closest point to it. Again the many destinations go into the first input and the few "origins" go to the second.

int nearpt = nearpoint(1,@P);
int prim = addprim(0,"polyline");
vector p2 = point(1,"P",nearpt);
int pt = addpoint(0,@ptnum);
setpointattrib(0,"P",pt,p2);
addvertex(0,prim,@ptnum);
addvertex(0,prim,pt);


LINE BY LINE

int nearpt = nearpoint(1,@P);
//get id number of point from second input to currently processed point's position
int prim = addprim(0,"polyline");
//create primitive of polyline type
vector p2 = point(1,"P",nearpt);
//set vector to nearpt's position
int pt = addpoint(0,@ptnum);
//add point at currently processed point's position
setpointattrib(0,"P",pt,p2);
//set position of new point to position of nearpt.
addvertex(0,prim,@ptnum);
//add vertex at currently processed point's position
addvertex(0,prim,pt);
//add vertex at nearpt's position

Wednesday 27 September 2017

writing alembics for maya - path attribute

Covered this in an older post, but this is for more straightforward cases when you want to define a group and shape node name for Maya purposes. We do this to avoid multiple shape names in Maya (eg. lots of pSphereShape1's or multiple Houdini Merge listings ; Alembic will take whatever the penultimate node to your ROP-alembic is called!)

In a primitive wrangle, this bit of code will create two text entry boxes, so you can input a group name and a shape name. If you were to call the group "squareGrp" and the name "square", then the resultant hierarchy would be "squareGrp/square/squareShape" in Maya.


string group = chs("MayaGroup");
string name = chs("Name");

group += chs("groupSuffix");
name += chs("geoSuffix");

s@path = group + '/' + name + '/' + name + 'Shape';


Remember to tick the "build hierarchy" box in the ROP-Alembic node & also to tick "use path".

Saturday 16 September 2017

Entagma snippet : drawing lines between a set of two points

This is useful when you want to connect two bunches of points together.. You'd think it'd be easy right?

Scatter, say 50, points on a grid. Then another 50 on another grid (or any shape..it doesn't really matter). Move them about a bit, then plug them both into a point wrangle (first two inputs).
This code will draw a single primitive edge between the points, paired by @ptnum (so you could do some sort of sorting beforehand, I guess):


int npnt=addpoint(0, @opinput1_P);

int nprim=addprim(0,"polyline");

addvertex(0,nprim,@ptnum);

addvertex(0,nprim,npnt);

Lets tackle each line.

int npnt=addpoint(0,@opinput1_P);
First we make a new point. Point wrangles only ever consider the first input's points. So we need to add the other input's points into the mix. I think the 0 corresponds to the @ptnum attribute.. So it looks up the relevant point in input1 and then puts it at the position specified by "@opinput1_P". That's a handy bit of VEX shortcutting there.

int nprim=addprim(0,"polyline");
Here we are creating a new primitive, of polyline type. Nothing is there yet...

addvertex(0,nprim,@ptnum);
Now we add a vertex to the primitive we just created. Firstly, we add the point we're currently processing.

addvertex(0,nprim,npnt); 
Next we add the vertex we added at the beginning (our currently processed point's counterpart in the other group).

That's it!

set colour according to bounding box.

now that the old Point node is more or less dead and buried, we have to rely on wrangles or vops to set our colours in fancy ways.

To give an object a gradient of colour based on it's bounding box (eg. black-to-red, from -ve to +ve on the x axis) we can use the relbbox function.
In a wrangle, we can type

@Cd=set(relbbox(@P.x),0,0);

tadah!

Tuesday 15 August 2017

Shattering an animated object. Eg. flying saucer smashing into something

Say you want to make a moving object smash into bits. Eg. A flying saucer that's been hand animated, which then needs to break apart dynamically.
As usual this isn't going to be straightforward :)

Shatter and pack geometry as usual, only what we need to do is ensure the points are not active. You can be double sure by laying down a point wrangle and setting i@active=0;

In your DOP network, make sure the RBD is not an active rbd as initial state. Set it to deforming static object. This should be done in the drop down menu. Now if you hit play, the object should not simulate at all & only follow it's given animation. "Overwrite Attributes" is NOT ticked.

We will use a sop solver & a point wrangle within to set the active value to 1. I've found using an activating shape like a box to set points into a group (using the bounding option) works best for this. eg. the saucer rbd points don't become active until they pass through said box. The attribute "deforming" (an integer) must be set to 0 once the "active" value switches to 1. This is so it no longer animates, or as Houdini refers to it, "deforms".
We use a sop solver so that the active value stays at 1 and doesn't reset to 0 once it passes through the activating shape. What we also need to do is use this sop solver in conjunction with the Bullet solver. This is done with a multi-solver.

Things I've found that are a bit problematic are glue constraints... Will look into this.
Update on glue - 

Houdini 16.0.504.2 has a weird thing... The Constraint Network's "Overwrite with SOP" attribute's default value is supposed to only import the SOP on the first frame...but it seems to behave as if it's always importing it. As a result, set it to 0 (zero), so that the animation of the object is ignored. This seems to make the glue constraints work properly.

https://drive.google.com/file/d/0B2eKYZ42BvalZnFaY0NZMkhwb3M/view?usp=sharing

Monday 17 July 2017

pyro - "custom wind volumes"

Sometimes you want to have pyro behave a certain way in a certain area. Eg.  the smoke should go from left to right, then suddenly shoot upwards after a few seconds.

Instead of fiddling with the advection or velocity updates, it's a bit simpler to create a separate pyro source that only emits velocity.
Simply create a source as you normally do, but remove it's density & temperature. Remember to scale these to zero in the DOP area too!