Almost every ICE tree involves getting data, performing calculations, and then setting data. You can get and set any data using Get Data, Set Data, and other nodes found in the Data Access category of the Tools tab. In addition, there are some compounds for getting and setting specific data in the Getters and Setters subtasks of the Particles and Deformations tasks in the preset manager.
Intrinsic ICE attributes include component attributes that correspond to actual geometric data in the scene, such as PointPosition, PointNormal, PolygonNormal, and so on. Some attributes are read-write, and others are read-only.
Note that many of the predefined attributes are not intrinsic but actually dynamic attributes that have been automatically set by certain nodes and compounds. These attributes are recognized by their names — for example, the SimulateParticles node recognizes the Force, PointVelocity, and Mass attributes. These predefined attributes always appear in the Get Data node's explorer, even if they haven't been set or initialized yet.
Dynamic attributes also include custom attributes. You can create your own custom attributes for any purpose you wish. Many of the attributes used in the factory compounds are actually custom attributes, such as AgeLimit, Init_PointVelcocity, and others. See .
When you get data by an explicit string reference, you get a set of values with one value for each component. For example, if you get "sphere.PointNormal", you get one 3D vector for each point of the sphere object; in other words, the context is per point of sphere.
When you get data at a location, the context depends on the context of the set of locations that is connected to the Source port of the Get Data node. For example, if you start by getting "grid.PointPosition", then use that to get the closest location on sphere, and in turn use that to get PointNormal, the data consists of normals on the sphere but the context is per point of the grid. If instead you started by getting "grid.PolygonPosition", the context would be per polygon of the grid.
You can set data using an explicit string reference only. You cannot set data at locations. To set an attribute, the data must be in the appropriate context. For example, to set PointPosition, the data must be in the per point context of the appropriate object. Not all attributes can be set.
You can get and set ICE attributes as many times as you like in a tree — each time you get an attribute, you get the latest updated values. However, you can set external data, such as kinematics or a regular property value, only once per tree — if you get it again after setting it, you get the original unchanged values.
If the current selection does not have a synoptic or annotation property, you can press F3 in a viewport to open a mini-explorer for the selection and drag from that. Otherwise, you can open the object's mini-explorer using Shift+F3.
To get data at a location, plug any location data into a Get Data node's Source port. When a location is plugged into the Source port of a Get Data node in this way, its Explorer button shows only the attributes that are available at that location.
You can use this technique to get data from other objects using geometry queries like Get Closest Location nodes. For example, you can get PointNormal at the closest location on a sphere. For more information on geometry queries, see .
The positions returned in this way are expressed in the local coordinate system of the object that the ICE tree is applied to (the "Self" object). The same is true of vectors like PointNormal and PointVelocity, but they are handled as vectors rather than as positions (translation is ignored). Custom 3D vector attributes are not converted automatically — it's up to you to decide if they need to be converted as a position, converted as a vector, or left unconverted. For information about converting between reference frames, see .
The important thing to realize about using the Get Data at Previous Frame node is that only the specific data retrieved by that node is evaluated at the previous frame. The following illustrations explain this in more detail.
The tree above calculates the closest locations on the sphere at the previous frame by getting both the point positions and the sphere at the previous frame. It then gets those locations' normals at the previous frame.
Be aware that the Get Data at Previous Frame node can have high processing costs, depending on the amount of data that it needs to evaluate at another frame. You can often improve the processing speed of your trees by storing data in custom attributes for use by the next frame, instead of using Get Data at Previous Frame.
If points are added and deleted, Get Data at Previous Frame returns the data for the component with the same index, not necessarily the same component. If there are no components with given indices at the previous frame, then the corresponding elements are filtered out of the data set and ignored by the downstream nodes.
To use both Get Data at Previous Frame and Set Data with an object, whether it's the self or another one, in the same ICE tree, the object must have a Simulation region in its construction stack. This applies even if you are getting and setting different attributes. Having a Simulation region in the stack means that the lower regions of the stack will be evaluated only on the first frame of the simulation, and subsequent frames will be based on the previous frame — see for more information.
The other attributes and properties that are available to get from below the group in the Get Data node's explorer are those that exist on each member of the group (intersection). Getting one of these attributes or values returns an array for each member of the requested data set. The size of the array is the size of the group, and the order of elements in the array corresponds to the creation order of the members of the group.
You can modify this order, if desired. In an explorer, choose View General Sort None (creation), activate View Reorder Tool, and drag and drop nodes within the group. The order is preserved when you save and reopen the scene. For more information, see .
When getting per-component data, such as PointPosition, the results are correct only when all objects in the group have the same number of components. As a workaround, one possible way to get, for example, all point locations is to plug the Get Data (group) node's value into the Geometry port of a Generate Sample Set node with Emission Type set to Point and Rate Type set to All Points.
You can connect the same Get Data node to as many nodes as you want if you need the same data elsewhere in the tree. However if the data has changed in-between, the Get Data node will return the new data later in the tree.
Attributes that belong to points, edges, and samples are interpolated from the surrounding components. The exceptions are certain NURBS-related attributes such as PointBinormal, which are calculated directly at locations on NURBS surfaces and curves.
When you use an explicit string reference to get transformation-dependent attributes such as positions, vectors, rotations, and so on, the raw, untransformed values are returned. These are typically expressed relative to the local space of the object that owns the components. For example, if you get "grid.PointPosition", the values are relative to the grid's local reference frame.
Once you specify a reference, the displayed name of the input port changes from Value to the name of the reference. If you connect a reference to the Set Data node's In Name, it is prefixed to all references defined in the Set Data node itself. This lets you use one Set Data node to set several attributes on the same object. However, when an object name is connected to In Name, you must add ports and specify their references before you can connect values; this is because the object name by itself does not resolve to any data type.
If you set ICE attributes and then get them later in the same tree, you get the modified values. However, you can set external data, such as kinematics or a regular property value, only once per tree — if you get it again after setting it, you get the original unchanged values.
If data has been set for some but not all components in a data set, uninitialized components have default values: zero for most data types, false for Booleans, identity for matrices, black for color, etc.
Attributes whose names begin with two underscore characters ("__") are hidden and not shown in attribute explorers. This can be useful if you have internal "bookkeeping" attributes inside compounds that you don't want users to fiddle with.
If you try to set data but never use it anywhere in the scene, it never actually gets set because of how ICE is optimized. This applies not only to custom attributes, but also to dynamic attributes — for example, if you try to set PointVelocity but don't use a Simulate node to update point positions, then PointVelocity does not get set.
If you can't plug a Set Data node into one of those ports — for example, if you are creating a compound that does one thing to new particles and another thing to old particles — you can filter on the Init attribute. See .
To create a custom attribute, simply use a Set Data node and make up a new attribute name. For a list of attribute names that are already used in ICE, see . Don't forget to include the full reference including the object name in the Set Data node, for example, "PointCloud.my_custom_attribute".
You can use custom attributes to store any type of value, including locations. The context and data type of custom attributes are determined by the connected nodes. If the data type is undetermined, the Set Data node is in error (red) — you can use a node from the Constant category to force a specific data type. If the context is undetermined, it defaults to the object context. However, this context can be changed to a component context if you connect nodes that force a different context, as long as there are no conflicting constraints on the context.
The Delay Set Data node holds the results for all Set Data nodes anywhere in the upstream nodes and executes them all at once. This allows you to set attributes that depend on each other. For example, you can swap values.
In the first example, the value of A is written to B, and then the value of B (which is now the old value of A) is written back to A again.
At the end, both A and B have the original value of A.
With Delay Set Data, B is set to the value of A but it is not written yet. Then A is set to the value of B and both get written together.
At the end, A has the original value of B and B has the original value of A.