A solution is to store your selected object name first and then deselect them after you separate the mesh.
Something like this:
org_obj_list = {obj.name for obj in context.selected_objects}
# This is a Set comprehension in Python,
# which create a set of name from the context.selected_objects
# context.selected_objects will be a Iterable collection of some object
bpy.ops.mesh.separate(type = 'SELECTED')
# This will call the separate operator in your code directly
# the type can be a enum string in ['SELECTED', 'LOOSE', 'MATERIAL']
bpy.ops.object.editmode_toggle()
# Switch back to object mode from edit mode
# Those separated object will also be selected now
# We then check if selected object is the one we saved before, then deselect it.
for obj in context.selected_objects:
if obj and obj.name in org_obj_list:
# Deselect selected object
obj.select_set(False)
else:
# Set the new created object to active
context.view_layer.objects.active = obj
Not sure if this is the best practice, but it do work.
A custom operator:
import bpy
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()
After register it as an Operator, you can search and run this operator in edit mode within 3d space:
Or in View3d > edit mode > mesh > Separate Selection Active after append a new menu function to make it searchable in Blender 2.90.
You should see a prompt asking a method for separating:
These options is exactly the same with original separate operator.
And this operator will separate it, deselected original mesh, make the new created mesh active:
Note: If the separate process make the one you want to be active unchanged, this operator will active the wrong mesh since it's still the original mesh with the same name.