Fail to join faces with python I would like to join two faces which are in the same mesh by using bmesh.utils.face_join(faces, remove=True), and the details from blender 2.78c  API documentation show:



Firstly, I had a square plane whose vertices are((-1, -1, 0), (1, -1, 0), (1, 1, 0), (-1, 1, 0)) 

Secondly, I used the following codes to add a triangle plane whose vertices are ((0, 0, 0), (2, 2, 0), (2, -2, 0)) to the mesh containing the square plane.

And then joined the square plane and the triangle plane together.

import bpy
import bmesh
from mathutils import Vector

# Setting scene and camera
scene = bpy.context.scene

# All objects in Scene
objects_in_scene = scene.objects
# get the square plane
for obj in objects_in_scene:
    if (hasattr(obj.data, "vertices")):
        squareObj = obj
        break

# vertices of the triangle plane
verts2 = [(0, 0, 0), (2, 2, 0), (2, -2, 0)]
# add vertices
squareObj.data.vertices.add(3)
squareObj.data.vertices[-3].co = verts2[0]
squareObj.data.vertices[-2].co = verts2[1]
squareObj.data.vertices[-1].co = verts2[2]

# change mode to editmode
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(squareObj.data)

# add the triangle face 
bm.verts.ensure_lookup_table()
set_of_verts = set(bm.verts[i] for i in range(4,7))
bm.faces.new(set_of_verts)

# update the bmesh
bmesh.update_edit_mesh(squareObj.data)

# join the two faces and print the new face
print(bmesh.utils.face_join(bm.faces, remove=True))


However, I got the error message bellow:


  TypeError: face_join() takes no keyword arguments


I modified the codes in the end line and use print(bmesh.utils.face_join(bm.faces)) instead.

The script could run but I got feedback, "None", which meant failure according to blender API documentation.



In fact, I am trying to merge two faces into one face with python like this.

I found this operation in blender 2.78c API documentation and tried it.

Please tell me if you have any suggestion about why can't use bmesh.utils.face_join(faces) and bmesh.utils.face_join(faces, remove=True), or how to merge two faces into one face with python.

Thank you in advanced.
okay so here is the information I can give you:


bmesh.utils.face_join(faces, remove=True) only works (in my tests) if the faces you provide are actually connected by an edge. If there is any other face involved that is not connected, the function will fail. This is the problem you are experiencing


therefore you need to programmatically select linked faces. (see 3.)


The indexes for the vertices are not guaranteed to be the same indexes. So range(4, 7) in your code in bmesh does not necessarily give you the same vertices you added earlier to the mesh.


I suggest, you add the face the same way you add the vertices, to the mesh datablock. Or, better, you should add the vertices to the bmesh like this:

v1 = bm.verts.new((2.0, 2.0, 2.0))
v2 = bm.verts.new((-2.0, 2.0, 2.0))
v3 = bm.verts.new((-2.0, -2.0, 2.0))

new_face = bm.faces.new((v1, v2, v3))


Edit: your new face might actually not share an edge with the existing faces. you should check that probably


Now that you have your face properly set up, you can try to feed linked faces into the bmesh.utils.face_join(linked_faces)


this is a function i wrote to get linked faces:

def get_linked_faces(f):

    if f.tag:
        return []

    f_linked = [f]
    f.tag = True
    # Select edges that link two faces
    edges = [e for e in f.edges if len(e.link_faces) == 2]
    for e in edges:
        faces = [elem for elem in e.link_faces if not elem.tag]

        if not len(faces) == 0:
            for elem in faces:
                f_linked.extend(get_linked_faces(elem))

    return f_linked


you will get an array of linked face groups:

f_link_map = []
for face in bm.faces:
    if not face.tag:
        linked_faces = get_linked_faces(face)
        f_link_map.append(linked_faces)



in the end of your operations it's also good practise to add

bm.free()


i hope that helps you. it took me quite a while to find out what the problem is in your case. also sorry, python formatting is quite an annoyance.