Bmesh - creating mesh from existing mesh - preserve edge connections

I’m writing a script to make a new mesh based of an existing mesh, for various reasons.

unfortunate the simplest test case fails, which happens to be the main shape that will be copied in practice to a new mesh.

(left bmesh, right source mesh)

going clockwise the source mesh indices go 0,2,3,1 but the code i’ve managed to write i guess assumes that the order to connect edges is sequential 0,1,2,3

I’m assuming i need to grab some more information from the source mesh, maybe what edges are connected to what indices and construct it that way instead of just forcing a new face from the given verts?

Anyway here’s my code

import bpy
import bmesh
ob = bpy.context.active_object
bpy.context.active_object.select_set(state=False)
# Loops per face
verts = []
#for face in ob.data.polygons:
#    for vert_idx, loop_idx in zip(face.vertices, face.loop_indices):
#        uv_coords = ob.data.uv_layers.active.data[loop_idx].uv
#        #print("face idx: %i, vert idx: %i, uvs: %f, %f" % (face.index, vert_idx, uv_coords.x, uv_coords.y))
        
        
for vx in ob.data.vertices:
    co_final = ob.matrix_world @  vx.co
    verts.append(co_final)
    #print(co_final, v.index)
    #print(verts)
    
mesh = bpy.data.meshes.new("mesh")  # add a new mesh
obj = bpy.data.objects.new("MyObject", mesh)  # add a new object using the mesh

scene = bpy.context.collection
scene.objects.link(obj)  # put the object into the scene (link)
bpy.context.view_layer.objects.active = obj  # set as the active object in the scene
#obj.select = True  # select object
bpy.context.active_object.select_set(state=True)


mesh = bpy.context.object.data
bm = bmesh.new()


verts = [bm.verts.new(v) for v in verts]


face = bm.faces.new(verts)
bm.normal_update()
#face.normal = (0, 0, -1)


# make the bmesh the object's mesh
bm.to_mesh(mesh)  
bm.free()  # always do this when finished

well, you gave it the verts in sequential order, what did you think was going to happen? :slight_smile:

you should iterate via loops rather than assuming ob.data.vertices is just going to have all of your face winding correct- i can’t think of a situation where it would be correct.
quick test on a plane using loops:

if you’re working with an existing mesh and already have a bmesh created it’s actually even easier since you don’t have to use a loop_indices list as a middle man and can get the BMVert index directly from the loop itself, but otherwise the concept is the same

1 Like