Geometry nodes uses vertices as points by default so when i feed the mesh to Point Instance it instances the selected object across the vertices. How do you switch to the centers of faces?enter image description here

enter image description here enter image description here enter image description here


4 Answers 4


Blender 3.0

For the future googlers. The answers are outdated. For version 3.0 you can use Mesh to Points Node with Faces option.

enter image description here

Getting normals for rotation is still a little tricky, though. You have to use capture attribute to get the normals from faces and use Align Euler to Vector to convert normal to rotation:

enter image description here

  • $\begingroup$ What is the radius 0.05 for? $\endgroup$
    – Neil
    Feb 17, 2022 at 21:28

Edit: This workaround is no longer necessary, see other answers

There is a pure GeoNodes workaround..

Please see below for GN (Fields) update.

Compare the original mesh to a 1-level subdivision of itself. Points on the subdivided version which are sufficiently distant from the edges of the original are in the middle of the original's faces, and can be separated out:

enter image description here

There has to be a tiny Epsilon in the Greater Than node to account for floating-point errors.. in this case, 0.0001.

GN(Fields) Update:

Just in case some have found some of this as counter-intuitive as I have, here is a route to one instance per face, aligned to normal:

enter image description here

..here shown with GN-modified mesh and instances together:

enter image description here

(Blender 3.0b)

  • $\begingroup$ This is a pretty smart sollution! GeoNodes still don't let us do it so ellegantly but your method will work about 100% of the time so it's alright. $\endgroup$ Sep 3, 2021 at 9:21
  • $\begingroup$ Re: update.. I'm finding it very difficult to work out which branch of geometry callbacks like 'Position' are being called on... :( $\endgroup$
    – Robin Betts
    Nov 13, 2021 at 13:44
  • $\begingroup$ The normals works only as if the obj is spherical. If you put a subbed cube you get skewed (spherically) pointing instances. Any thought on that issue? $\endgroup$
    – BrainCrash
    Dec 13, 2021 at 12:54

i think this is not possible with the current version of geometry nodes.

But you could do it with the help of this python script:

import bpy
import bmesh
from mathutils import Vector

print("*" * 50)

obj = bpy.context.object

prevMode = obj.mode

# Will need to be in object mode
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)

# Create a bmesh access
bm = bmesh.new()
bm.from_mesh( obj.data )

# Get faces access

# Identify the wanted faces
faces = [f for f in bm.faces]
faceNormals = [f.normal for f in bm.faces]

newVerts = []

for eachFace in faces:
#    print("new face:")
    x = 0
    y = 0
    z = 0
    for eachVertex in eachFace.verts:
#        print("vert:",eachVertex.co)
        x = eachVertex.co.x + x
        y = eachVertex.co.y + y
        z = eachVertex.co.z + z
    noOfVertsInFace = len(eachFace.verts)
    avgX = x / noOfVertsInFace
    avgY = y / noOfVertsInFace
    avgZ = z / noOfVertsInFace
    newVerts.append((avgX, avgY, avgZ))
verts = [v for v in bm.verts]       

bmesh.ops.delete( bm, geom = faces, context = 'FACES_ONLY' )
bmesh.ops.delete( bm, geom = verts)

for v in newVerts:
bm.to_mesh( obj.data )

# Back to the initial mode
bpy.ops.object.mode_set(mode=prevMode, toggle=False)

how can you use it?

  1. select your object which you want to use (better make a copy of it and save that because your original object/mesh will be changed)
  2. run the script
  3. now you can use geometry nodes with that changed object

what does the script?

The script iterates over each face. For each face it iterates over all vertices and calculates the average point ("center"). It then deletes all existing faces and vertices and creates vertices at these centers.

  • $\begingroup$ Thank you! It's a pity they haven't yet implemented that into blender tho $\endgroup$ Aug 30, 2021 at 13:28
  • 1
    $\begingroup$ +1, ... It's not really my area, but I think you could crunch your code quite a lot by using bmesh.ops.poke(), which will pop a vertex in the middle of all faces in a given list. If you keep a record of the original verts, you can then delete those. $\endgroup$
    – Robin Betts
    Aug 30, 2021 at 19:34

Another option is to use a Dual Mesh Node. My only question is: is it more efficient? I don't know. node tree result


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .