How To Add The Mesh From One Object To Another?

Hi All,

I have this small routine which accepts two meshes as input. One mesh is the host mesh and the other is the addition mesh. The goal is to combine both meshes into a single mesh, like join. But this routine will be run in a frame change so it needs to be event friendly and be able to execute while rendering as well.

For some reason, this code completely pulls down Blender. Not even a crash. Blender just goes bye-bye when I run this code. The crash happens when I issue a polygons.add().

Does anyone have an alternate way to join meshes? Or any insights as to how to fix this code?


import bpy

def addToMesh (passedHostMesh, passedAdditionMesh):
    fl = len(passedHostMesh.polygons)

    print("Initial face length:" + str(fl) + " for [" + passedHostMesh.name + "].")
    # Transfer the vertices from the append to the host.
    num_v = len(passedHostMesh.vertices)
    num_append_v = len(passedAdditionMesh.vertices)
    passedHostMesh.vertices.add(num_append_v)
    for v in range(num_append_v):
        # However, we need to offset the index by the number of verts in the host mesh we are appending to.
        passedHostMesh.vertices[num_v + v].co = passedAdditionMesh.vertices[v].co
    
    print("Appending face...")
    # Now append the faces...
    num_f = len(passedHostMesh.polygons)
    num_append_f = len(passedAdditionMesh.polygons)
    print("Count %i" %  num_append_f)
    
    # When I issue this next line, Blender disappears completely.
    #-->
    passedHostMesh.polygons.add(num_append_f)
    #<--
    
    print(str(num_f) + ", " + str(num_append_f))
    for f in range(num_append_f):
        print("1")
        x_fv = passedAdditionMesh.polygons[f].vertices
        print("2")
        o_fv = [i + num_v for i in x_fv]
        # However, we need to offset the index by the number of faces in the host mesh we are appending to.
        if len(x_fv) == 4:
            print("3a") 
            passedHostMesh.polygons[num_f + f].vertices = o_fv
        else: 
            print("3b")
            passedHostMesh.polygons[num_f + f].vertices = o_fv
    
    print("Attempting to update and calculate edges.")
    #passedHostMesh.update()
    #passedHostMesh.update(calc_edges=True)
    fl = len(passedHostMesh.polygons)
    print("Final face length:" + str(fl) + " for [" + passedHostMesh.name + "].")

The attached BLEND file has the whole scene setup for testing. Open up the BLEND and run the script to observe the crash.

Thanks

Attachments

266_addToMesh.blend (85.2 KB)

geometry changes on frame change event is really not what frame change handlers were made for, and it’s not really astonishing that it hangs / crashes blender if you try. Can’t to process geometry before rendering?

I didn’t read any part of the top code (only thing I read is the add polygon error)
did you try to make a container --> pass one object points/polygons list to it -> clear that object data -> take the other object list?
like what you do when importing meshes
verts = []
faces = []
mesh = bpy.data.meshes.new(“NewObject”)
mesh.from_pydata(verts,[],faces)

Here’s what works for me -using bmesh- but curious to know how to do it right


## join some meshes ##

import bpy, bmesh
sel = bpy.context.selected_objects
mes = bmesh.new()

for obj in sel:
    tmp = bmesh.new()
    tmp.from_object(obj, bpy.context.scene)
    tmp.transform(obj.matrix_world)
    num = len(mes.verts)

    for nv in tmp.verts:
        mes.verts.new(nv.co.to_tuple())
    mes.verts.index_update()
    for nf in tmp.faces:
        vvv = [num + v.index for v in nf.verts]
        mes.faces.new([mes.verts[v] for v in vvv])
    tmp.free()

malla = bpy.data.meshes.new('malla')
suma = bpy.data.objects.new('suma', malla)
bpy.context.scene.objects.link(suma)
mes.to_mesh(malla)

@Atom: by changing geometry i mean adding/removing geometry, editing existing geometry should be fine. And mesh interchanging is what i still consider “existing geometry”. That’s deffo what app handlers are for, agreed! But adding/removing geometry “on-the-fly” seems problematic to me.

@Liero: Thanks. I have removed the previous code types for generating faces and replaced them with your Multi-Extrude code. Along with the mesh join you just provided, Bleeble lives again! An animated version of Multi-Extrude that supports multiple selection sets that you can cycle through over time or display simultaneously as seen below.


Because Bleeble is an actual object you can apply modifiers to it as well. Here is a Bleeble with subdivision surface applied.

With Bleeble you can also use a selection set to simply remove faces from final mesh generation.


@CodemanX: You are correct, it can be problematic but it is possible. For creation of objects and meshes on-the-fly to work you must adopt a strict naming convention for referncing everything and use .remove() to make sure you leave no datablocks hanging around in memory. Also, you must never reference a datablock that has been removed. But caveats are what scripting is all about, right?