Attributes
An important concept in Geometry Nodes is attributes. Many trees transfer attributes between geometry, using a combination of Capture Attribute and Transfer Attribute.
Unfortunately, it takes quite a bit of code to use this common pattern.
@tree("Skin")
def skin():
# Create a cube
c = cube()
# Capture the position
cube_position_attribute = c.capture_attribute(
data_type=CaptureAttribute.DataType.FLOAT_VECTOR,
value=position()
)
# Create a sphere
sphere = uv_sphere()
# Transfer the position to the sphere
transferred_position = cube_position_attribute.geometry.transfer_attribute(
data_type=TransferAttribute.DataType.FLOAT_VECTOR,
attribute=cube_position_attribute.attribute
)
# Make the sphere conform to the shape of the cube
return sphere.set_position(position=transferred_position)
Thankfully, a convenient capture(...)
method is available on Geometry
, which simplifies this function quite a bit.
@tree("Skin")
def skin():
# Create a cube
c = cube()
# Capture the position
cube_position = c.capture(position())
# Create a sphere
sphere = uv_sphere()
# Make the sphere conform to the shape of the cube
return sphere.set_position(position=cube_position())
How it Works
Internally, capture(...)
works just like the more manual approach.
- Capture the attribute from the source
In the example above, we capture the position()
from the cube.
The data type is automatically inferred from the input. If you want to customize other options, simply pass them as keyword arguments to capture(...)
.
cube_position = c.capture(position())
cube_position = c.capture(position(), domain=CaptureAttribute.Domain.FACE) # Optionally pass other arguments available on `capture_attribute`.
- Transfer the attribute to the target
capture(...)
returns another function that calls transfer_attribute
with the correct arguments passed automatically.
Call this returned function (which we store in the variable cube_position
) to transfer the attribute.
In this example we also set the transferred cube position back onto the sphere.
sphere.set_position(position=cube_position())
sphere.set_position(position=cube_position(mapping=TransferAttribute.Mapping.NEAREST)) # Optionally pass other arguments available on `transfer_attribute`.