1
$\begingroup$

I have the following mesh. It is a series of hexagons placed on a plane.

I'm trying to select random hexagons to give them another material. I know there is a select random function, but that only works on vertex, edges and faces. I'm trying to do it by loose parts.

Is there an option to do this?

enter image description here

$\endgroup$

2 Answers 2

3
$\begingroup$

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.

enter image description here

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()
$\endgroup$
1
  • $\begingroup$ This is even better! $\endgroup$
    – S.Visser
    Commented Sep 22, 2018 at 13:33
4
$\begingroup$

To select hexagons randomly as in your case, you must use the random function with vertex, edges or faces.

Then simply press " CTRL and L " as mentioned Duarte.

Or press several times " CTRL and Numpad + " to add all part of the hexagons.

$\endgroup$
1
  • 2
    $\begingroup$ Ctrl + L Select Linked operator would probably be more adequate here $\endgroup$ Commented Sep 21, 2018 at 2:11

You must log in to answer this question.

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