# Select neighbour faces from a mesh with python

I am new to blender and python and try to get the hang of it. PS: Everything should be achieved via python script.

I want to create a low poly model via ico-sphere. That's really easy because I just need to create a ico-sphere. Now I want to randomly select a face and one of his neighbours to merge them via bpy.ops.mesh.edge_face_add() to a new face.

I am having the following script:

bpy.ops.object.mode_set(mode = 'EDIT') # into edit mode
bpy.ops.mesh.select_all(action='DESELECT') # deselect everything
bpy.context.tool_settings.mesh_select_mode = (True , False , False) # only faces
mesh=bmesh.from_edit_mesh(me) # get mesh
mesh.faces.ensure_lookup_table() # update faces
mesh.faces[0].select = True # select face number 0
mesh.faces[1].select = True # select face number 1
bpy.ops.mesh.select_all(action='DESELECT') # deselect everything


At first I am using bmesh which is experimental. I would like to use a blender api which isn't experimental. Any ideas? I tried it with faces[0] and 1 and it worked, they are neighbours. But I think that's not always. How can I find out which faces are next to faces[0] for example.

Thanks for helping!

• TextEditor > Templates > Python > Bmesh Simple Editmode

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data

bm = bmesh.from_edit_mesh(me)

face = bm.faces[3]
face.select = True

# This gives the list of all edges that use that vertex.
# [<BMFace(0x7f7acb5ddb70), index=52, totverts=4>,
#  <BMFace(0x7f7acb5ddbe0), index=54, totverts=4>,
#  <BMFace(0x7f7acb5ddba8), index=53, totverts=4>,
#  <BMFace(0x7f7acb5dd0b8), index=3, totverts=4>]

bmesh.update_edit_mesh(me, True)


There's also link_edges which could also prove useful, arguably more so

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data

bm = bmesh.from_edit_mesh(me)

# just assume now there is only one selected face
selected_face = [f for f in bm.faces if f.select][0]

for edge in selected_face.edges:
face.select = True

bmesh.update_edit_mesh(me, True)


produces

And finally, the join command

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data

bm = bmesh.from_edit_mesh(me)

# just assume now there are at least 2 selected, and are touching
selected_faces = [f for f in bm.faces if f.select]

# the script equivalent of the F key
bmesh.ops.contextual_create(bm, geom=selected_faces)

bmesh.update_edit_mesh(me, True)


Regarding your statement about Bmesh being experimental, I wouldn't worry about that too much, it's being used a lot and has proven to be more than capable. The Bmesh.ops docs are an excellent but admittedly terse resource:

• Wow, Thanks! That helped a lot! :) One thing I am a bit puzzled is the bmesh.ops.contextual_create(bm, geom=selected_faces), which is equivalent to bpy.ops.mesh.edge_face_add(). Why are there two methods which are doing the same? What is more correct? contextual_create or edge_face_add()? – Hamburml Apr 25 '15 at 13:28
• bpy.ops.* and bmesh.ops.* are different routes to operate on meshes. The two functions you mention may be in some way equivalent, but if you have a reference to a bmesh, then you don't use bpy.ops. Think of bmesh as a virtual Mesh until you call update_edit_mesh on it. Whereas bpy.ops.* requires the mesh directly. I've probably not explained that very well... sorry. – zeffii Apr 25 '15 at 13:38
• Naaah, you don't need to apologize. Thanks for helping! I will try it right now :-) – Hamburml Apr 25 '15 at 13:44
• Thank you! It's working but I need to call mesh.faces.ensure_lookup_table(). I think it is because I create the object a few lines above in my script. – Hamburml Apr 25 '15 at 13:56
• yeah, i didn't want to potentially complicate a simple example. – zeffii Apr 25 '15 at 14:37