Dupe n Delete
Similarly to another answer re materials and "normalizing" material slots (removing unused), can use a default dictionary with a list of the vertices of each vertex group, then remove others from from a dupe for each group.
Ultimately this would be better if could split using bmesh, but as of now cannot set a split target to another mesh or bmesh instance.
Note this will split based on vertex group. Vertices that are members of more than one group will be in each split off object. Vertices not assigned to any group will not be split off into new object.
Using copy
on both the object and the mesh brings along all data.
import bpy
from collections import defaultdict
import bmesh
context = bpy.context
ob = context.object
me = ob.data
vgs = ob.vertex_groups[:]
col = context.collection
rg = defaultdict(set)
for v in me.vertices:
for g in v.groups:
rg[vgs[g.group]].add(v.index)
bm = bmesh.new()
all_verts = set(range(len(me.vertices)))
for vg, verts in rg.items():
if not verts:
continue # no empty vg mesh
oc = ob.copy()
oc.name = vg.name
me = oc.data = oc.data.copy()
bm.from_mesh(me)
bm.verts.ensure_lookup_table()
bmesh.ops.delete(bm,
geom=list(bm.verts[i] for i in (all_verts - verts)),
context='VERTS',
)
bm.to_mesh(me)
bm.clear()
for g in oc.vertex_groups:
if g.name != vg.name:
oc.vertex_groups.remove(g)
col.objects.link(oc)
Note I haven't bothered to remove materials, as mentioned this is similar to a previous script used in one of your answers, to test what materials are on a face and remove.
Alternatively, instead of copying a new mesh each time, copy the bmesh and write to a new mesh. Once again will have to deal with materials, using all faces left after delete operator, to check which materials are assigned to faces of a particular vertex group.
See Delete all materials that aren't assigned to a face?
If the material is data (mesh) linked, can append to the Mesh.materials
collection instead of using the slot operators.
import bpy
from collections import defaultdict
import bmesh
context = bpy.context
ob = context.object
me = ob.data
vgs = ob.vertex_groups[:]
col = context.collection
rg = defaultdict(set)
for v in me.vertices:
for g in v.groups:
rg[vgs[g.group]].add(v.index)
bm = bmesh.new()
all_verts = set(range(len(me.vertices)))
bm.from_mesh(me)
for vg, verts in rg.items():
if not verts:
continue # no empty vg mesh
oc = ob.copy()
oc.name = vg.name
oc.data = bpy.data.meshes.new(vg.name)
bmc = bm.copy()
bmc.verts.ensure_lookup_table()
bmesh.ops.delete(bmc,
geom=list(bmc.verts[i] for i in (all_verts - verts)),
context='VERTS',
)
bmc.to_mesh(oc.data)
bmc.free()
for g in oc.vertex_groups:
if g.name != vg.name:
oc.vertex_groups.remove(g)
col.objects.link(oc)