Since a vertex belongs to more than one face, your evaluate on face domain is actually interpolating between top and side faces, creating different results.
New solution without "Repeat Zone"
Since repeat zone is very costly, it's better to use just. But to avoid interpolation between top and side faces, we use "face of corner" to select exactly from which face we want to take the position and rotation
Explanation:
- We are setting positions for vertices (so every value is evaluated per vertice)
- If we change the evaluation domain to faces, since we're still evaluating vertices, the results for each vertice will be an interpolation between all faces one vertice is connected to
- So we use "evaluate at index" with one "face index" to evaluate for one specific face instead of interpolating
- This face should be the "top" face, and the node that does this selection is "Corners of vertex"
- Each vertice has a number of corners (= number of faces)
- This lists all corners, sorts them based on "ascending weights", picks the one with
index=0
(the one with the lowest weight)
- We just need to pass "weights" in a way that the "top face" has the lowest weight
- The "Top" selection from the extrude node has value = 1 for top and 0 for the other faces. We invert this with the "subtract" so the top has value 0 and the others have value 1 and connect it to the weights
Old solution
Using "repeat zone" is never a great solution, but I think in this case it's the way to go.
Here, we loop each original face and extrude them individually.
This way we can take a mean of the vertices and evaluate things on a single face. (This would also allow you to separate the original face and take its center if you want the "arms" to be rotated together with the top faces)
(If you're on Blender 4.3, you can use a "Foreach element" instead of a repeat zone, and a few nodes could be discarded)
File with both solutions