Skip to content

Commit

Permalink
Update Data Copying Section.
Browse files Browse the repository at this point in the history
  • Loading branch information
OmarEmaraDev committed Oct 31, 2018
1 parent 1fadd09 commit b6f1a63
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions docs/user_guide/getting_started/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,24 @@ A vectorized node has vectorized sockets, such sockets change from list types to
Data Copying
============

Users of Animation Nodes don't have to worry about data copying as Animation Nodes automatically copy data if needed, however, sometimes, control over whether data should be copied is given to the user, such control is only needed for advanced uses of subprograms and data editing nodes. The options to control data copying is provided in the *Advanced Node Settings* of the nodes that supports it.
Data types in Animation Nodes are either *mutable* or *immutable*, mutable means the data type can be edited/mutated and immutable means it can not. For instance, lists are mutable, but integers and floats are not. To understand the difference, we shall look at two nodes, the *Add* node and the *Remove List Element* node, which process immutable and mutable data types respectively.

To have a better understanding of data copying and a possible situation where control over it might be needed, consider the following example (*The following example is rather advanced and requires good knowledge of loops. You may skip it if you are just getting started*).
- The *Add* node takes an input number, read its value, add that value to another value, and return the result of addition. The value of the input was not altered/mutated in anyway, the node only read its value, and the output is a new different value containing the result of addition.
- The *Remove List Element* node takes an input list, removes an element from it, and return the list. The output list is the same list that was input, only it was mutated/altered by removing an element from it.

A loop is constructed such that it appends a float to an initially empty float list parameter provided a condition is satisfied at each iteration. The conditional appending is achieved by conditionally reassigning the float list parameter to the list after appending. *Notice that using a conditional generator may not be an option because access to the generated list at each iteration might be needed.* Now, consider the situation where we only reassign if the index is larger than 2, if the number of iterations is 5, we should expect the float list to contain two floats, but upon viewing it, we see it actually contains five elements realizing that the conditional reassigning is rendered ineffective. Why is that?
Mutable objects introduces certain complications, for instance, if one added two *Remove List Element* nodes, one of which removes the first element and the other removes the last element, upon viewing the result of both nodes, we find that both output lists have their first and last elements removed, what happened here? Since the input list is mutable, one node edited the list by removing the first element and the other edited the same list by removing the last element, when one view both output lists, one is actually viewing the same list that was edited, hence the result. But if one wants two versions of the list, one with only the first element removed and one with only the last element removed? To allow that, Animation Nodes perform what is known as data copying. Basically, Animation Nodes make multiple copies of the list and gives every node a different copy, that way, the results of each node are independent of each other. In the case of the foregoing example, Animation Nodes makes two copies of the list, gives one copy to each node, each node edits its own copy and return it without affecting the other.

Animation Nodes automatically copy data if it thinks copying is needed. If Animation Nodes decides to copy data, you have no way to instruct it not to, on the other hand, for certain nodes, an option to enforce data copying even if Animation Nodes decides not to is given to the user, such control is only needed for advanced uses of subprograms and data editing nodes. The options to enforce data copying is provided in the *Advanced Node Settings* of the nodes that supports it. Generally, Animation Nodes decides to copy data if this data is used by multiple nodes, but assuming the state of copying of a certain data unless you explicitly enforce it is a bad practice.

One of the nodes that allow one to enforce data copying is the loop node, a possible use case is introduced in the following rather advanced example. A loop is constructed such that it appends a float to an initially empty float list parameter provided a condition is satisfied at each iteration. The conditional appending is achieved by conditionally reassigning the float list parameter to the list after appending. **Notice that using a conditional generator may not be an option because access to the generated list at each iteration might be needed.** Now, consider the situation where we only reassign if the index is larger than 2, if the number of iterations is 5, we should expect the float list to contain two floats, but upon viewing it, we see it actually contains five elements realizing that the conditional reassigning is rendered ineffective. Why is that?

.. image:: images/copying_example_1.png

You see, the *Append To List* node appends the float to the original list because the *Loop Input* node handed it without copying (The default no-copying behavior is chosen for performance superiority.), subsequently, it doesn't matter whether we reassigned the list or not because the original data is already altered and by the end of the loop, all floats will have been appended. The solution to this is to instruct the loop to copy the data before handing it, this can be done by enabling *Copy* for the float list parameter. Upon enabling it, we see the expected two-element output float list.
You see, the *Append To List* node appends/adds the float to the original list because the *Loop Input* node handed it without copying (The default no-copying behavior is chosen for performance superiority), subsequently, it doesn't matter whether we reassigned the list or not because the original data is already altered and by the end of the loop, all floats will have been appended. The solution to this is to instruct the loop to copy the data before handing it, this can be done by enabling *Copy* for the float list parameter in the advanced node settings. Upon enabling it, we see the expected two-element output float list.

.. image:: images/copying_example_2.png

Notice that Animation Nodes may enforce copying of the parameter on its own if needed. For instance, by connecting the float list parameter to any other node, Animation Nodes feels the need to copy the data and enforce it **even if copy option is disabled**.
Notice that Animation Nodes may enforce copying of the parameter on its own if needed. For instance, by connecting the float list parameter to any other node, Animation Nodes feels the need to copy the data and enforce it **even if copy option is disabled**.

.. image:: images/copying_example_3.png

Expand Down

0 comments on commit b6f1a63

Please sign in to comment.