0
$\begingroup$

I'm creating a simple script in which I need to separate selected faces. The one I have now only works for 1 object:
https://gyazo.com/a660dc1a8f9543ab8c6c12759e5de114

But when I'm editing multiple objects at once, you get this outcome: https://gyazo.com/edc6f3c57f00d8a81041ecf73bf6ea4d

import bpy

selection = bpy.context.selected_objects

for o in selection:
    
    bpy.ops.mesh.duplicate_move(MESH_OT_duplicate={"mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 5), "orient_axis_ortho":'X', "orient_type":'GLOBAL', "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)), "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, True), "mirror":False, "use_proportional_edit":False, "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "use_proportional_connected":False, "use_proportional_projected":False, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "cursor_transform":False, "texture_space":False, "remove_on_cancel":False, "view2d_edge_pan":False, "release_confirm":False, "use_accurate":False, "use_automerge_and_split":False})

class SeparateSelectionActive(bpy.types.Operator):
    """Separate object by selection and set it as active object."""
    bl_idname = "mesh.select_separate_active"
    bl_label = "Separate Selection Active"
    
    # An enum for prompt dialog
    separate_method: bpy.props.EnumProperty(
        items = {
            ('SELECTED', 'Selected', "Selected mesh"),
            ('MATERIAL', 'Material', "Based on material"),
            ('LOOSE', 'Loose', "Based on loose part")
        },
        name = "Separate Method",
        description = "Choose a method to separate mesh",
        default = 'SELECTED'
    )
    
    @classmethod
    def poll(cls, context):
        return context.object is not None and context.mode == 'EDIT_MESH'
    
    def invoke(self, context, event):
        # Prompt to ask a method to separate
        return context.window_manager.invoke_props_dialog(self)

    def execute(self, context):
        org_obj_list = {o.name for o in context.selected_objects}
        
        # Separate using selected method
        bpy.ops.mesh.separate(type = self.separate_method)
        bpy.ops.object.editmode_toggle()
        for obj in context.selected_objects:
            if obj and obj.name in org_obj_list:
                # Deselect everything selected before
                obj.select_set(False)
            else:
                # Set the new created object to active
                context.view_layer.objects.active = obj
                self.report({'INFO'},f"Set active object to: {obj.name}")
        return {'FINISHED'}

# A menu inject into View3D > Edit > Mesh tab
def _menu_func(self, context):
    self.layout.operator(SeparateSelectionActive.bl_idname)

def register():
    bpy.utils.register_class(SeparateSelectionActive)
    bpy.types.VIEW3D_MT_edit_mesh.append(_menu_func)

def unregister():
    bpy.utils.unregister_class(SeparateSelectionActive)
    bpy.types.VIEW3D_MT_edit_mesh.remove(_menu_func)

if __name__ == "__main__":
    register()

    # test call
    bpy.ops.mesh.select_separate_active()
$\endgroup$

1 Answer 1

1
$\begingroup$

That is because you are looping at line $5$. Selecting 2 faces duplicates them on the first iteration and then again on the second iteration, resulting in 4 faces.

You just need to remove line $5$:

for o in selection:
$\endgroup$
4
  • $\begingroup$ Now its not working at all $\endgroup$ Aug 19, 2022 at 11:10
  • $\begingroup$ lol c'mon you can do better than that. obviously you have to unindent line 6 after removing the loop :) $\endgroup$ Aug 19, 2022 at 11:15
  • 1
    $\begingroup$ Yes, you're right. THANKS NOW ITS WORKING ! $\endgroup$ Aug 19, 2022 at 11:23
  • $\begingroup$ np, you're welcome $\endgroup$ Aug 19, 2022 at 11:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .