属性#
‘Capture Attribute’ nodes are inserted automatically when required
Be sure to be familiar with fields: Blender reference documentation.
Geometry property#
Fields such as Index or Position represents a value (Integer, Float, Vector…) associated to a domain (Point, Edge,…) of a geometry.
In a Blender tree, the geometry a field belongs to is found by following the links forwards and backwards (see Blender Field).
A field is a geometry property
In geonodes, fields are implemented as properties of class Geometry. In the following example (extracted from Blender documentation), we use two fields of input geometry: Index and the Position.
import geonodes as gn
with gn.Tree("Geometry Nodes") as tree:
geo = tree.input_geometry
v = geo.position
v = v.scale(scale=geo.index)
geo.set_position(offset=v, node_color="green")
tree.output_geometry = geo
In the resulting tree, Position and Index nodes are fields of the input geometry because their links “join” at the green node ‘Set Position’:
Let’s add another ‘Set Position’ node after the second one, fed by the same offset input. This second node is colored in blue.
import geonodes as gn
with gn.Tree("Geometry Nodes") as tree:
geo = tree.input_geometry
v = geo.position
v = v.scale(scale=geo.index)
geo.set_position(offset=v, node_color="green")
geo.set_position(offset=v, node_color="blue")
tree.output_geometry = geo
THE RESULTING TREE IS NOT THE FOLLOWING
In the tree above, the fields Index and Position are evaluated twice, one for the green node and one for the blue node. These two nodes are fed by two different geometries, hence the fields Index and Position take different values.
The tree resulting from the second script is the following:
Since the python script defined the index
and position
as property of the initial geometry (v = geo.position
), it understand that a ‘Capture Attribute’ node is necessary to feed the blue node.
On the illustration below, we can see the three resulting meshes with the same default cube as input:
‘Capture Attribute’ insertion#
geonodes module inserts ‘Capture Attribute’ nodes whenever required. As a consequence the second tree will never be generated by geonodes:
To produce this result, you must explicitly get the index
and position
of the transformed geometry as illustrated below:
import geonodes as gn
with gn.Tree("Geometry Nodes") as tree:
geo = tree.input_geometry
# Fields from the initial geometry
v = geo.position
v = v.scale(scale=geo.index)
geo.set_position(offset=v, node_color="green")
# Fields from the transformed geometry
v = geo.position
v = v.scale(scale=geo.index)
geo.set_position(offset=v, node_color="blue")
tree.output_geometry = geo
The resulting tree is the following.
There is not anymore ‘Capture Attribute’ node because it is useless, but there are now two ‘Index’ nodes and two ‘Position’ nodes, one for each geometry.
from imare import *
init_modules(__file__, "imare", "geonodes")
flush_data()
import geonodes as gn
from geonodes.nodes import nodes
import numpy as np
rad = np.radians
with gn.Tree("Geometry Nodes", reroute=False) as tree:
geo = tree.input_geometry
v = geo.position.scale(scale=geo.index)
geo.set_position(offset=v, node_color="yellow")
v = geo.position.scale(scale=geo.index)
# 连续的`set_position`会新增`capture_attribute``
geo.set_position(offset=v, node_color="light red")
tree.og = geo
Tree({
O.cube @ "Cube": {
Mod.geometry_nodes: {
"node_group": "Geometry Nodes",
},
},
}).load()