The Output-type suboperators, including Amount Change, have options to define the Priority order and Execution order. When creating complex setups, it's important to be aware of these options.
The order of the data modification and processing is defined by the Output suboperators. The Output suboperators drive data modification. They pull particle data out of suboperators above them in the data flow, and set the data as particle properties.
Output suboperators with the same Execution Order value deal with the same input data. When the Execution Order value is the same, the Priority Order value defines the order in which the Output suboperators pull the data from upstream. Only after all the data are pulled are the data are applied to particle properties.
If suboperators have different Execution Order value then they might deal with different input data, even if they pull the data from the same Input suboperator. This is because an Output suboperator with a lower execution order might change the data in some particle property. When the output suboperator with higher execution order pulls the data, these data have been already modified.
Consider this example: When particles come into an event, you need to calculate initial values for all new particles. Then you want to modify particle properties in every frame (regardless if a particle is new in event or not), and during this modification you need initial values to be set in all particles.
For this scenario you have two data streams: the first stream calculates the initial values; and the second stream modifies particle properties. The Output suboperator for the first stream should have Execution Order=1, and most likely its filter input will be set to Input Standard New In Event. The Output suboperator in the second stream should have Execution Order=2.
Consider another scenario: You want to analyze speed data in all particles, and, depending on some condition, you would like to define two subsets of particles, each of whose speeds will be modified in different ways. For this scenario you have to use two Output suboperators with the same execution order. This way you guarantee that the initial input speed values are the same for each Output.
Incidentally, because the Amount Change suboperator changes the number of particles, it cannot share its Execution Order value with any other suboperator. Safeguards in the program prevent you from doing so.
Also, the Execution And Priority Order group also has Pre/Normal/Post radio buttons. This option defines the processing order on a higher level. If it set to Pre then this output is done before any operators in the current event are executed. If it is set to Normal, then the output suboperator is executed in the regular order, in-between the other operators in the same event. If it is set to Post then the output is processed after all operators and all tests in this particle system have finished their jobs for this integration step.
For an example that illustrates Pre/Normal/Post usage, open the included file CollisionAsBody.max.
This example uses the Data operator to produce "cheap and quick" full-body collision. As you probably know, particle systems in 3ds Max treat particles as point entities with regard to collisions and deflectors. Therefore, if a particle has a shape with visible size, the shape penetrates the deflector surfaces, which can ruin the overall visual effect. The example shows how to wire particle data to offset the particle position by the amount of the inter-penetration.
First, we create a custom data channel to store real values, as the position offset needed to avoid the penetration. For all new particles we initiate this value to zero—see data block 01.
After all the other operators and tests have done their job, we calculate the amount of penetration, and offset particle position in Post phase. This way particle positions are adjusted to avoid penetration and the particles are ready for rendering. The Output operators on the right side do their jobs in the Post phase.
Then, in Pre phase, we need to move particles back, to their no-offset positions, for the collision tests to continue their job as if nothing has happened.
Particle systems are inherently history dependent. In other words, to be able to determine the state of a particle system at, say, frame 100, the software has to calculate the states for all previous frames since the first particle is born. This is because the changes in particle properties—for example, the positions of the particles—accumulate due to the constant changes in other parameters, such as speed.
However, for particular setups some particle properties are not history dependent, and can be calculated from the current state of the particles. For example, the orientation of the particles if they "look at" something such as the camera, or follow particle speed. Here the orientation of the particle depends either on particle position, as is the case when facing the camera, or particle speed. In this case, to calculate the current orientation of the particles, you don't need to know the entire history of the particles; you just need to know their current speed or position.
In that sense, the operator that calculates particle orientation is not history dependent. The operator does not have to do anything while the system runs through all prior frames in order to get to the current frame. The operator has to work only on the final frame; to analyze the position/speed of the particles in the final frame and calculate the corresponding particle orientation.
If you are sure that the result of the Output suboperator does not depend on the history of particles, you can turn off the History-Dependent option. This can speed up the overall calculations, as it causes the Data operator to work at the last frame only.