Tuesday 2 October 2018

emitting only 1 particle per point per frame


Obviously stole this from ODforce:

if you want just 1 particle emitted per point at a given frame, the basic expression would be in the rate of the source node of your pop network
if you decide to put it in the impulse rate :
npoints(opinputpath("../",0))
and turning off the const. activation
if you decide to put it in the const rate
npoints(opinputpath("../",0))*$FPS
and turning off the impulse activation
don't forget to put the emission type to points(ordered) or you won't have a particle per point
this will hower emit the exact amount of points your emitter sop has per frame, so if your emitter has points that last 2 frames, you'll have 2 particles per point after 2 frames.


*Also, you could use $NPT/10 instead of npoints... Dunno if this works

When would you use this?
If you have a source which is changing point count each frame, eg, a pattern of cracks being animated (like when Godzilla is underneath a road)... 

I think the $FPS version helps when it comes to substeps etc like with Maya, where you need to divide the perframe emission to account for the substeps... 

The first option works well if you divide the emission count (just add a /10 or whatever after the expression)

Monday 25 June 2018

Gas field in specified area, alternate...

But wait, there's more!
Another approach I've found on the webs, is to make a Gas Match Field, which makes a new field based on some other value.. eg. Density or Temperature.
You can actually specify a Density that is not the Pyro-sim's density, by using a Source Volume (turns out they don't always have to go into the last input). Point that to your custom volume
Finally, set the control mask to your new field.

All three of these nodes should be plugged into a single merge, which then goes into the Velocity Update of the pyro solver. (or the advect...)

I think this approach might be more flexible, if you are using it to refer to an internal pyro-value like Density or Temp?

Another approach I've seen skips the external source volume and copies the Temperature from the pyro solver itself. They use Gas Match to make a field which is "equal" in size/type to Temperature,
Next they use a gas calculate node to copy the Temperature to the custom field,

Finally, They  use a gas field wrangle to fiddle with the newly created field. Normalise values, or do whatever..

They use the custom field as a mask for dissipate & turb.
Quite a neat way to mess around with the temperature.

Gas field only in specified area. Stolen from the Sidefx site

  1.  In the DOP network, add a SOP Scalar Field node after the Pyro object.
    • Turn on Use SOP Dimensions.
    • Set the SOP path to the path of the fog volume object (for example /obj/mask_object). Make sure Use Object Transform is on.
    • Set the Data Name to something indicating the purpose of this field, for example NoiseMask.
    This attaches the fog volume as field data on the Pyro object with the given name.
  2. Create a Gas Turbulence node and connect it to the fourth ("Advection") input of the Pyro solver.
    • On the Bindings tab, set the Density Field to the name of the mask data, for example NoiseMask. The effect of the node is multiplied by the value of this field.
    • Use the controls on the Turbulence Settings tab to control the amount of turbulence added.


      Important thing to note - by default the control field will not be 100% in control.. You'll see some "leakage" of turbulence. This is because the Control Influence is set to 0.5 by default.. Whack it up to 1, and maybe tweak the remap-graph to fine tune the effect of the turb/whatever.

Saturday 14 April 2018

access 2nd input in a wrangle

point(1, "P", @ptnum);
probably posted something about this before... but the "1" here lets you access the 2nd input's data.

Thursday 12 April 2018

Quick note about Houdini hair

when using Houdini's toolbar hair tools, pay attention to the highest-level node's parameters.
The groom should take place on a static mesh (laydown a timeshift node), and the deform node will do the movement magic.

Thursday 5 April 2018

Exporting curves to Maya

When exporting curves to Maya as arnold ASS files, you can export "pscale" (this can remain a point value) for thickness. Note, it can be varied along the length of the curves, to create variation/tapering etc. A good way to preview the pscale is to add a "polywire" node. You might have to use pscale/2 for the polywire radius. (remember to blast most of your curves first if there are lots and lots of them!)

In the options for the Arnold archive output, make sure the "export Asstoc file" box is ticked. This creates the bounding box info for the curves.


u value tip

With lines, instead of calculating U values by dividing @ptnum by @numpt, you could - at the very start of the process -  add a float attribute (using Attribute Create), with the value set to @ptnum. Lines by default only have 2 points, so pt 0 will have a value of 0 and pt 1 will be set to 1.

You then could resample the lines once they've been copied onto points (eg for hairs), by minimum distance, so that they are divided more evenly. The U value will have been interpolated correctly.

Thursday 22 March 2018

alembic rotation transform

matrix m = primintrinsic(0,'packedfulltransform',@ptnum);@orient = quaternion(matrix3(m)); 


Stole this from odforce. I'm unsure whether it's meant to be in a point or primitive wrangle (and then promoted to the other). I managed to get it working in just a point wrangle..This helps you get rotational values from an alembic'd object (v. handy!)

point cloud open, point cloud iterate, point cloud import, while loop VOPS

I'll probably never memorise the proper VEX code for iterating points in a point cloud:

pcopen(something something what?)

So lets look at how to do a basic VOPS setup.

  1. Lay down a "Point Cloud Open" node. Connect the P attribute into P.. and then most likely you'll want to plug Opinput1 into the "file" input. "File" refers to the points you are running over. Set the radius and max number of points to whatever you want. They are probably going to be useful promoted to SOP level.
  2. Make a "Point Cloud Iterate" node. Plug the result "handle" of the Point Cloud Open node into this. The "handle" is a list of all the points that are within the radius you specified earlier. The iterate node is generally used in conjunction with a ....
  3. "While" loop node. The iterate node's handle is used as the opening condition for the While loop. As long as we're running through the points within range, the loop will continue. So plug the Iterate's "Success" output into Condition.
  4. Attach the "handle" from Point Cloud Open to one of the other While Loop inputs. This is important!
  5. Attach anything else you want processing into the other inputs of the While Loop. Eg. Maybe Cd? Or a constant value.
  6. Within the While loop, make ANOTHER "Point Cloud Iterate". We're going to use this is to ensure the While loop ENDS. Hook up the "handle" you attached in step 4, into the input of the iterate. Then connect it's output to the While Loop's End block condition.
  7. OK! The loop is fine now. We can use a "Point Cloud import" node to get any data we want. We'll use the "handle" value from step 4 again as an input. Make sure to set the parameters correctly. Eg. if a value is a float,vector,integer etc.
  8. Do what you want...maybe import the X position of a point and add it to the red of Cd?
  9. Plug any outputs into the While Loop End's box
  10. Connect the outputs to things. It might be the global output, or to some bind-exports.
And that's the basics!

Tuesday 13 March 2018

simple vector field avoidance

based on this vid's ideas...
https://www.youtube.com/watch?v=MWJ0E1Rdoiw

As an example case: You have a grid space with some cylinders scattered about. On the X side of the grid space you have a bunch of particles being emitted. We want the particles to flow through the space avoiding said cylinders.


  • We make a Volume that encompasses the whole area in question. We give it a vector value and name it Vel. For velocity.
  • We make a volume VOP. The volume we just made goes into input 1. The cylinders go into input 2.
  • Inside the VOP we make a constant vector value of (1,0,0). This is the direction we want the particles to go in. That's X.
  • We make an XYZdist node and plug our Position and Input 2 bits in. We're getting the distance to the nearest faces with this.
  • We want the Normal attribute of the faces. To get this, add a Primitive Attribute node. Plug in the relevant parts from XYZdist. Remember to feed in Input 2, for the "file" input. Change the attribute to N. We now have the Normal. Add a Normalize node to keep the maths clean.
  • Do a cross product between the constant X and our normalized Normal. Normalize this too.
  • Do another cross product between the normalized cross product and our normalized normal. This is a bit fiddly, but it's all about 90 degree angles and getting to what we want.
  • Normalize the result and plug it into a Bind Export with the attribute named Vel.

We now have the basis of a vector field.
However it'd be nice to use the distance from the cylinders as a blending function. So if you're in a bit of the field not close to a cylinder, you'd just go on about your way.. Only as you got closer would you be affected. To do this............

  • Go back into the VOP. Connect the Dist output from the XYZdist node into a Fit Range Node.
  • Promote the Source Maximum input. We'll set this later outside of the VOP.
  • Plug the output of the Fit Range into a Ramp parameter. Set the ramp to a linear type.
  • The output of the ramp can go into the Bias input of a Mix node.
  • Constant X goes into input A of the Mix. The normalized result of the 2 crossproducts goes into input B. The output of the Mix can now be plugged into the Bind Export we made before.
Outside of the VOP we need to reverse the ramp parameter so that at 0 (ie. very close to the cylinder) we have maximum effect (ie. a value of 1). And at 1 (ie. further away from the cylinders) we have a value of 0. The Maximum distance could be anything depending on scene size. Try 10 & then work up or down. 

Finally.. this can be used in a POP network now, to override a particle system's velocity! 

Tuesday 6 March 2018

calculating nice uvs for polywires/regular surface

int div=`chs("../polywire2/div")`;
@uv.x=float(@ptnum%div)/div;

f@numRows=float(@numpt)/div;


i@rowNum=@ptnum/div;
@uv.y=float(@rowNum)/float(@numRows);


I then promote this to a vertex attribute...not sure why I didn't do it via vertx in the first place ...

The channel bits of code "chs...." just refer to the number of divisions down the tube. eg an 8 sided cylinder.

This setup keeps the UVs within 0-1 space.