1.  Particle Size by
Inter-Particle Distance
2A.  Speed in Direction
Part 1
2B.  Speed in Direction
Part 2
3.  Particle Displacement

Tutorial 1. Particle Size by Inter-Particle Distance
(Beginning Level)

In this tutorial we explore some ways to control particle size to avoid particle overlapping. The tutorial uses deep particle data control of Box #3 Pro. If you don't have Box #3 Pro, you can download demo version at http://www.orbaz.com/download/

Suppose you want to place particles on all vertices of a reference object. Of course, you can use the Position Object+ PFlow operator (see the relevant topic here.) However, with Box #3 Pro you have a more procedural way of doing that.

Note: For the Position Object+ operator to work properly, you need to have the same amount of particles as the number of vertices on the reference object. If you change the topology of the reference object, you will have to find the new number of vertices in the mesh and adjust Birth operator to match this count. Well, although that’s not much of a hassle, we cannot call it truly procedural.

1. Let’s create a default PFlow particle system and a sphere with radius 40. Then, open Particle View and delete Position Icon, Speed, Rotation and Shape operators — we won’t need them.
2. Change the timing in the Birth01 operator to Emit Stop = 0, and number of particles to one (Amount = 1). Drag-and-drop a Data Preset operator under the Birth operator, and select Particle Per Vertex preset. As a result, a new data preset operator is created. The only parameter of this operator is the button to define the reference object — select the sphere that we created earlier. Now you can see that all vertices of the sphere are covered with the particles, and we did not even bother to find how many of them there are.
Note: If you are interested in how the Particle Per Vertex custom preset works, you can create a new Data Operator; use the Load Preset button to load the Particle Per Vertex preset, and then open Data View and analyze the schematics of the data flow (this one is not that big). However, this is not the goal of the tutorial.
3. Now we can add a Shape Plus operator to define the shape of the particles. Select 3D Sphere 80–sides for nice round particles. Shape Plus is one of the Box#1 operators — if you don’t have it, you can download the demo version on the web page that I mentioned earlier. Adjust the Display operator's show type from Ticks to Geometry in the upper drop-down list. As you can see, the default size value 10 makes particles too big, and they overlap one another.

Note:. With the release 2010, Box#1 was integrated in 3ds Max and functionality of a Shape Plus operator is available as a Shape operator. Therefore, if you work with 3ds Max 2010 or later, you can use a Shape operator.
Let’s change the size value to 5. Now we can see a lot of singular particles, though in the area of the polar caps the particles are still overlapping. I have to decrease the size value to 2 in order to avoid overlapping. However, now that the particles are small, the majority of the sphere is quite bare.
It would have been nice to be able to make particle size depend on the density of the particles so that where we have a lot of them their size is reduced, and in the areas of low particle density their size is larger.

This goal is easily achievable with the Particles suboperator. Before diving into the data flow river, let’s change the particle size value to 1 — this is our unit value for size.
4. Create a new Data Operator below the Particle Per Vertex operator. Open Data View for this new Data Operator and drag-and-drop a Particles suboperator. The default aggregated property of the Particles suboperator is Closest Particle Distance — it is exactly what we need. When Particles is set to this property, for each particle in the event it calculates the distance to the closest particle. We can use this distance to figure out the proper particle size.

First, let’s check what are the actual values that the Particles suboperator calculates for us. Suboperators in Data View are optimized in a way that they work (proceed particles) only if their results are actually needed. Data operators communicate with the rest of the PFlow particle system by using Output suboperators; suboperators would work only if they are wired to Output suboperators.
Select the Particles suboperator that we created earlier, and then drag-and-drop an Output New suboperator. We selected the Particles suboperator to have an automatic match between the output type of the Particles suboperator and the input type of the Output New suboperator. An Output New suboperator has numerous data types, and in order to save a trip to the suboperator UI for the Data Type drop-down list adjustment, we can just select the Particles suboperator before creating an Output New suboperator.

Now we can wire together the Particles and the Output New suboperators. An Output New suboperator creates a new data channel in the particle system — the data values are taken from the suboperator that is wired to the Output New suboperator. Later, you can read the data from this new data channel by using an Input Custom suboperator, or write back into the data channel by using an Output Custom suboperator. Each Output New suboperator creates its own data channel — the more Output New suboperators you have, the more data you keep along with your particle system.
5. Now, when the closest-particle-distance values are calculated by the Particles suboperator (because Output New suboperator pulls these data into your particle system) we can quickly check them. But wait, they are still not calculating! — Why? Because we have the Auto Update parameter in our Data Operator which is by default is turned off. This is done to minimize the delays in Data View editing so you are committed to the changes in data flow only when you close Data View. When you turn on Auto Update check box, the changes in Data View are propagated immediately in your particle system. Alternately, you can click on Update button to commit to the current changes in Data View — do it now.

Now we can check out what our Particles suboperator is calculating. Right-click on Particle suboperator and select Show Data — that will show the actual data values that the Particles suboperator has generated for each particle. We can see that for the very first particle (that is on the polar cap of the sphere) the distance to the closest particle is 7.84. Then, for a bunch of particles (ones in the first polar cap row), its all the same value: 1.53 — everything is quite understandable.
6. Since the current particle shape size has a unit value, we can use the closest particle distance value as a multiplication factor for particle scale. We can do it by creating an Output Standard suboperator; choosing Scale / Average, and then wiring the Particles output to the input of the Output Standard suboperator. You need to click the Update button in the Data Operator again to see the result, if you did not select the Auto Update check box previously.
Now our particles have a variable size that depends on the local density of the particles, and this is all procedural — you can change the number of segments in the sphere, and the number of particles and their size is changed accordingly.

As a final polishing step, we can delete the Output New suboperator — the one we have used for data stream verification at the initial stage of scene creation.
7. One more note worth mentioning: Closest Particle Distance is a CPU-intensive operation. In the current setup it is recalculated in every frame. This may be needed if your geometry is animated, and the particles are moving. This, however, is a waste of CPU cycles if the particles are static. In that case we can calculate particle size only once when they enter the event. To restrict the calculations to the new particles only, we need to wire some filter control to the Particles suboperator - create an Input Standard suboperator and select New In Event, then wire the suboperator output to the filter input of the Particles suboperator. This will effectively limit the processing of the Particles suboperator to the particles that are just coming into the current event.