(Using Blender 3.6.8)
(NB: documentation to be continued...)
Acknowledgement: This proposal is adapted from the "quadratic geometry explosion" algorithm developed by Markus von Broady to solve "Compute on all points in geometry nodes". It takes also advantage of the test case introduced by Gordon Brinkmann in his proposal.
Objectives
Approach
GeometryNodes modifier
In what follows, the main graph is split in sequential parts that are discussed one at a time. To ease the display, previous parts might be off-window, and next parts are deleted. Nodes under discussion are in dark red. Extra nodes, not included in the main graph, are in dark green; these are added to display more information than required to perform efficiently the task.
Step 1
1. The 2D test case is based on a Grid
node coupled to a Distribute Points on Faces
node to create a Point Cloud. To limit the number of points to 4, the Density Max parameter is decreased from 10 to 0.5.
2. To visualise the Point Cloud, different mesh primitives are instanced on Points, ticking the Pick Instance parameter.
3. A Geometry to Instance
node is used to make an ordered collection from a Cone
, a Cube
, a Cylinder
(with 3 vertices, so a "Prism") and an Ico Sphere
.
4. The Index of each point is added "by hand" through a collection of labels to be displayed in the 3D Viewport.
Step 2
1. To compute the vector $\vec{x_j}-(\vec{x_i}+\vec{s})$, an occurrence of the original Point cloud is firstly transformed, such that new point coordinates are $\vec{x_{i}^{*}} = -\vec{x_i}-\vec{s}$, through a Transform Geometry
node.
2. A component-wise Scaling by (-1,-1,-1) is used to compute $-\vec{x_i}$ from $\vec{x_i}$.
3. Because Translation is applied after Scaling, the Shift vector $\vec{s}$ is pre-multiplied by -1, to compute effectively $\vec{x_{i}^{*}} = -1 \times \vec{x_i}+(-1 \times \vec{s})$.
4. Consequently in the 3D Viewport, comparing Step 1 and Step 2 display, mesh primitives are moved by a symmetry about the origin, then by a translation opposite to $\vec{s}$ (i.e. upwards in the test case as $\vec{s}$ is set to -0.4 along the Y axis).
Step 3
1. To create $N \times N \ (i,j)$ pairs, both input sockets of an Instance on Points
node are connected to the same Point Cloud object, except that one occurrence was "symmetrized and shifted" at Step 2.
2. Index $i$ is arbitrarily associated to the Points socket, while index $j$ is associated to the Instance socket. Both are captured in Point domain for later usage before the Instance on Points
node.
3. Vector $\vec{x_j}-(\vec{x_i}+\vec{s})$ is computed by a Realize Instances
node as the instanced points position. Indeed this node is shifting the instanced objects position (i.e. $\vec{x_j}$) by the "instancer" point position (i.e. $\vec{x_{i}^{*}} = -(\vec{x_i}+\vec{s})$).
4. Consequently, 16 points are displayed in the Spreadsheet editor. To visualize simultaneously $i$ and $j$, these are transiently stored as Named Attributes explicitly. Viewer
node is showing that captured and stored values are the same.
5. Side note: It is to notice that the building sequence of the Instance on Points
node is running the "inner" loop on $j$ (column index) and the "outer" loop on $i$ (row index), i.e. as in a row-oriented table.
6. All $N \ (i,i)$ pairs are located at the same position (i.e. $-\vec{s}$) by construction. It is highlighted with a blue square in the 3D Viewport.
Step 4
1. A Delete Geometry
node set in Point domain is removing self-interactions, i.e. points such that $i=j$.
2. Consequently, only 12 points are remaining in the Spreadsheet editor, and the blue square is now empty in the 3D Viewport.
3. To visualise $(i,j)$ pairs position, the same object "$(i)$" as at Step 2 is instanced. Besides "$i,j$" value for each point is added "by hand" through a collection of labels.
Step 5
1..
2..
3..
4..
5..
6..
7..
8..
9..
10..
Step 6
1..
2..
3..
4..
5..
6..
7..
8..
9..
10..
Step 7
1..
2..
3..
4..
5..
6..
7..
8..
9..
10..
Resources
Additional GN graphs
Comparison
Blender file