How create two new a objects(mesh) from single selection

I'm need create 2 difirence a object from one selection. I have some code but blender gives out error.

face_lengths = tuple(map(len, faces))

TypeError: object of type 'MeshPolygon' has no len()

import bpy

act_obj = bpy.context.active_object

sv = list(filter(lambda p: p.select, act_obj.data.vertices))
se = list(filter(lambda p: p.select, act_obj.data.edges))
sf = list(filter(lambda p: p.select, act_obj.data.polygons))

me = bpy.data.meshes.new("mymesh")
me.from_pydata([],[],[])

obj = bpy.data.objects.new("Object", me)
scene = bpy.context.scene


• If I understand you well, you want to create two objects, one corresponding to the selected parts and another corresponding to unselected parts? That's it? – lemon May 10 '17 at 6:16
• Not quite. Both corresponding to the selected – Влад Киндюшов May 10 '17 at 7:22
• So, two new objects, from the selected parts in the original object? And without changing the original object? – lemon May 10 '17 at 7:33
• Yes! Forgive me for my English – Влад Киндюшов May 10 '17 at 7:50

Ideally you could use bmesh.ops.split() but the option to copy to a new mesh is still unsupported.

Using bmesh you can copy the selected verts and faces and create a new mesh out of them, then use that in a new object.

import bpy
import bmesh

act_obj = bpy.context.active_object

if act_obj.mode == 'EDIT':
bm = bmesh.from_edit_mesh(act_obj.data)
else:
bm = bmesh.new()
bm.from_mesh(act_obj.data)
new_mesh = bmesh.new()

onm = {} # old index to new vert map
for v in [v for v in bm.verts if v.select]:
nv = new_mesh.verts.new(v.co)
onm[v.index] = nv

for f in [f for f in bm.faces if f.select]:
nfverts = [onm[v.index] for v in f.verts]
new_mesh.faces.new(nfverts)

scene = bpy.context.scene

new_data = bpy.data.meshes.new("mymesh1")
new_mesh.to_mesh(new_data)
obj = bpy.data.objects.new("SplitObj1", new_data)

new_data = bpy.data.meshes.new("mymesh2")
new_mesh.to_mesh(new_data)
obj = bpy.data.objects.new("SplitObj2", new_data)

bm.free()
new_mesh.free()

• It seems that's exactly what I need, thanks – Влад Киндюшов May 10 '17 at 9:23
• Something went wrong i.imgur.com/JHS49Hl.gifv – Влад Киндюшов May 10 '17 at 19:51
• Made an adjustment. The original script only looked at the object mesh data, while you go into edit mode and change the selection it was only looking at the previous selection stored with the object. – sambler May 11 '17 at 4:57

After selecting the vertices you want, separate them using:

bpy.ops.mesh.separate(type='SELECTED')

• I'm need 2 objects – Влад Киндюшов May 9 '17 at 21:38
• @ВладКиндюшов this will give you two objects – Tak May 9 '17 at 23:14
• Forgive me for my English, I know him very badly. So I get 1 new and 1 old object. And I need 2 new 1 old. If I use> bpy.ops.mesh.separate (type = 'SELECTED') I will go 2 times in edit mode. To tozhe there will still be difficulties with knitting this. I need to create 2 new objects with the date of the selected polygons – Влад Киндюшов May 10 '17 at 0:12

An alternative proposal.

The code is fully commented below, but feel free to ask for more details

import bpy

def a( context, duplicateAmount ):

print( '----' )
act_obj = context.active_object

if act_obj:
previous_mode = act_obj.mode #Keep current mode
previous_objects = set( context.scene.objects ) #Keep already created

try:
#Object mode to get updated selected faces
bpy.ops.object.mode_set(mode='OBJECT')
selected_faces = [p.index for p in act_obj.data.polygons if p.select]

#Edit mode in order to use duplicate and separate operations
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.duplicate_move() #(give a warning because context is normally using the UI, but no consequences)
bpy.ops.mesh.separate(type='SELECTED')

#Back to object mode
bpy.ops.object.mode_set(mode='OBJECT')
#Set the selected faces as at the beginning
for i in selected_faces:
act_obj.data.polygons[i].select = True

#Get the new object
new_object = next( o for o in context.scene.objects if o not in previous_objects )
new_object.update_from_editmode() #Ensure internal data are ok
#Copy it n - 1 times
for i in range( duplicateAmount - 1 ):
obj = new_object.copy()
obj.data = new_object.data.copy()
except: #If there is not selection, for instance
pass
#Set the original object as active again
context.scene.objects.active = act_obj
#Set it to the mode it had at the begining
bpy.ops.object.mode_set(mode=previous_mode)

a( bpy.context, 2 )


-----------------------------------------------------

import bpy
import bmesh
select_obj = bpy.context.selected_objects

def a():
act_obj = bpy.context.active_object
sf = [i.index for i in bmesh.from_edit_mesh(act_obj.data).faces if i.select]
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.duplicate_move(MESH_OT_duplicate={"mode": 1})
bpy.ops.mesh.separate(type='SELECTED')

bpy.ops.object.mode_set(mode='OBJECT')

sel_obj = bpy.context.selected_objects
object_B = None
object_B_Name = None
for i in sel_obj:
object_B_Name = i.name
object_B = i
break
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(act_obj.data)
bm.faces.ensure_lookup_table()
for i in sf:
bm.faces[i].select = True

bpy.ops.mesh.duplicate_move(MESH_OT_duplicate={"mode": 1})

bpy.ops.mesh.separate(type='SELECTED')
bpy.ops.object.mode_set(mode='OBJECT')

sel_obj = bpy.context.selected_objects
object_C = None
object_C_Name = None
for i in sel_obj:
object_C_Name = i.name
object_C = i
break
print("object_B ====",object_B)
print("object_C ====",object_C)
bm.free()
a()
bpy.ops.object.select_all(action='DESELECT')
for i in select_obj:
print(i)
i.select = True