I have loose mesh elements within an object and I would like each loos element to be placed in its own vertex group.
Asked
Active
Viewed 1,184 times
2 Answers
4
Another take on this. Already had code that separated a mesh into vertex groups from seams,
import bpy
def island_verts(mesh):
import bmesh
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bm = bmesh.from_edit_mesh(mesh)
bm.verts.ensure_lookup_table()
verts = [v.index for v in bm.verts]
vgs = []
while len(verts):
bm.verts[verts[0]].select = True
#bpy.ops.mesh.select_linked(delimit={'SEAM'})
bpy.ops.mesh.select_linked()
sv = [v.index for v in bm.verts if v.select]
vgs.append(sv)
for v in sv:
bm.verts[v].select = False
verts.remove(v)
bm.free() # prob not nec.
bpy.ops.object.mode_set(mode='OBJECT')
return vgs
# test run
obj = bpy.context.object
mesh = obj.data
vgs = island_verts(mesh)
for vg in vgs:
group = obj.vertex_groups.new()
group.name = "Island"
group.add(vg, 1.0, 'ADD')
batFINGER
- 84,216
- 10
- 108
- 233
-
1Thanks for the code. For some reason, though it adds a vertex group for each vertex – dimitarsp Nov 18 '15 at 15:50
-
Test the code against the cube (1 vgroup) or suzanne (3 vgroups, the eyes are separate). Could be something to do with your mesh. Try using p in edit mode, separate by loose parts, my guess is you will end up with as many objects as vertex groups it added from running the script. Probably why it's crashing TLousky's code as well, too many bmesh instances. – batFINGER Nov 18 '15 at 16:10
-
As for some reason, when testing it now, it works. Thank you :) – dimitarsp Nov 19 '15 at 16:14
-
I also get separate vert groups for each vertex, with both samples of code. Not sure if there is something that has changed with the API or with BMesh to cause it though. – Craig D Jones Jan 18 '17 at 04:33
-
Ah, found my problem and the solution is simple: the script actually looks for the object in edit mode to be in vertex select - if it is in edge or face select, that will not work, and you will get a vertgroup for every vertex then. Thank you for the examples, I want to set this as a tool now :D – Craig D Jones Jan 18 '17 at 04:43
1
Here's a script that iterates over each mesh island and assigns its vertices into a new vertex group.
EDIT - WARNING: After testing it appears that this solution is limited to around 1000 islands (due to Blender's max recursion limit). Use @batFINGER's solution if you have more vertex groups than that.
It's based on a recursive function since the blender API currently doesn't provide (as far as I know) any built in way to get all mesh islands.
import bpy, bmesh
def find_island_and_assign_vgroup( o, remaining ):
''' Recursive function that itertaes over mesh islands and assigns a new vertex group to each'''
if len( remaining ) > 0:
# Create bmesh object (must do this every time since vertex groups are created in object mode, which destroys the bm object
bpy.ops.object.mode_set( mode = 'EDIT' )
bm = bmesh.from_edit_mesh( o.data )
bm.verts.ensure_lookup_table()
bpy.ops.mesh.select_all( action = 'DESELECT' )
bm.verts[ list(remaining)[0] ].select = True
bm.select_flush( True )
bpy.ops.mesh.select_linked()
selected_verts = [ v.index for v in bm.verts if v.select ]
# Add to a new vertex group
bpy.ops.object.mode_set( mode = 'OBJECT' )
vg = o.vertex_groups.new()
vg.add( selected_verts, 1.0, 'ADD' )
# Remove this island's verts from the vert list
now_remaining = remaining - set( selected_verts )
bm.free()
find_island_and_assign_vgroup( o, now_remaining )
o = bpy.data.objects[ bpy.context.object.name ]
all_verts = set( range( len( o.data.vertices ) ) )
find_island_and_assign_vgroup( o, all_verts )
TLousky
- 16,043
- 1
- 40
- 72
-
Thanks for the script. Unfortunately it crashes Blender for some reason. – dimitarsp Nov 18 '15 at 16:01
-
Weird, worked for me. Can you upload a blendfile? http://blend-exchange.giantcowfilms.com/ – TLousky Nov 18 '15 at 16:03
-
1A bm.free() before the recursive call is probably a good idea, as that's what prob crashes your code on high loose part counts, given the OP's comment on the answers we've provided. – batFINGER Nov 19 '15 at 10:37
-
-
It doesn't crash now, but actually that's not enough either, as blender sets a maximum recursion depth to ~1000 (stopped in vertex group 992 in the Suzanne X3 test you suggested). So appears like your solution is more robust. – TLousky Nov 19 '15 at 10:43
-
Thanks, yes it doesn't crash now. @batFINGER's solution appears to calculate a bit faster. Happy there are more than one approaches :) – dimitarsp Nov 19 '15 at 16:16
