Bmesh Script
Using the script from here (which happened to come up today re another q) that finds all loose parts in a mesh.
Test script, run in edit mode on a mesh. Selects a random loose part on each run.
import bpy
import bmesh
from random import randint
def walk_island(vert):
''' walk all un-tagged linked verts '''
vert.tag = True
yield(vert)
linked_verts = [e.other_vert(vert) for e in vert.link_edges
if not e.other_vert(vert).tag]
for v in linked_verts:
if v.tag:
continue
yield from walk_island(v)
def get_islands(bm, verts=[]):
def tag(verts, switch):
for v in verts:
v.tag = switch
tag(bm.verts, True)
tag(verts, False)
ret = {"islands" : []}
verts = set(verts)
while verts:
v = verts.pop()
verts.add(v)
island = set(walk_island(v))
ret["islands"].append(list(island))
tag(island, False) # remove tag = True
verts -= island
return ret
#test code
context = bpy.context
ob = context.edit_object
me = ob.data
bm = bmesh.from_edit_mesh(me)
islands = [island for island in get_islands(bm, verts=bm.verts)["islands"]]
if len(islands):
#deselect all
for v in bm.verts:
v.select = False
bm.select_flush(False)
for v in islands[randint(0, len(islands) - 1)]:
v.select = True
bm.select_flush(True)
bmesh.update_edit_mesh(me)
Possibly more useful, re a scripting solution, would be to randomly assign materials from a list to loose parts.
Here the single mesh array of suzannes has 6 materials, which are assigned to each loose part randomly.
#test code
context = bpy.context
ob = context.object
me = ob.data
bm = bmesh.new()
bm.from_mesh(me)
islands = [island for island in get_islands(bm, verts=bm.verts)["islands"]]
for island in islands:
#deselect all
for v in bm.verts:
v.select = False
bm.select_flush(False)
for v in island:
v.select = True
bm.select_flush(True)
mat_index = randint(0, len(me.materials) - 1)
for f in bm.faces:
if f.select:
f.material_index = mat_index
bm.to_mesh(me)
me.update()