0
$\begingroup$

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
scene.objects.link(obj)

enter image description here

$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – lemon May 10 '17 at 6:16
  • $\begingroup$ Not quite. Both corresponding to the selected $\endgroup$ – Влад Киндюшов May 10 '17 at 7:22
  • $\begingroup$ So, two new objects, from the selected parts in the original object? And without changing the original object? $\endgroup$ – lemon May 10 '17 at 7:33
  • $\begingroup$ Yes! Forgive me for my English $\endgroup$ – Влад Киндюшов May 10 '17 at 7:50
1
$\begingroup$

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)
scene.objects.link(obj)

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

bm.free()
new_mesh.free()
$\endgroup$
  • $\begingroup$ It seems that's exactly what I need, thanks $\endgroup$ – Влад Киндюшов May 10 '17 at 9:23
  • $\begingroup$ Something went wrong i.imgur.com/JHS49Hl.gifv $\endgroup$ – Влад Киндюшов May 10 '17 at 19:51
  • $\begingroup$ 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. $\endgroup$ – sambler May 11 '17 at 4:57
1
$\begingroup$

After selecting the vertices you want, separate them using:

bpy.ops.mesh.separate(type='SELECTED')
$\endgroup$
  • $\begingroup$ I'm need 2 objects $\endgroup$ – Влад Киндюшов May 9 '17 at 21:38
  • $\begingroup$ @ВладКиндюшов this will give you two objects $\endgroup$ – Tak May 9 '17 at 23:14
  • $\begingroup$ 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 $\endgroup$ – Влад Киндюшов May 10 '17 at 0:12
1
$\begingroup$

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()
                context.scene.objects.link( obj )
        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 )
$\endgroup$
0
$\begingroup$

I do not like this method but it works.

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

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
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.