0
$\begingroup$

I have imported a character that has "mesh hair" and would like to animate it with Cloth. To Pin the roots of this complicated mesh to the scalp, I need to find and Group the "root" vertices of each segment, of which there appear to be many, even after using Mesh Clean Decimate to reduce vertices. Is there some (python?) method to find and group these?

manual pin group

enter image description here

$\endgroup$

1 Answer 1

0
$\begingroup$

I have found a python solution to effectively find vertexes to pin.

I the base/complete mesh, I first defined a Vertex Group called "pinned".

The hair was a series of meshes, so I first separated each into its own with the Edit Mode Mesh "Separate" "By Loose Parts":

enter image description here

I created a "pin.target" object near the crown of the scalp, to calc distance of each vertex I visit I then created a python script that did a select pattern to find all of the "strand" objects, and for all strand objects, for each vertex...

import bpy
import bmesh
from math import sqrt

pinTargetLoc = bpy.data.objects['pin.target'].location
print("pinTargetLoc=",pinTargetLoc)

bpy.ops.object.select_pattern(pattern="ToulouseHR*")
hairParts = bpy.context.selected_objects

cnt=0
bpy.ops.object.select_all( action='DESELECT' ) # Deselect all objects 
for hairPart in hairParts:
#    if cnt>0:
#        continue
    print( hairPart, hairPart.location )
    hairPart.select_set(True)
    bm = bmesh.new()   # create an empty BMesh
    bm.from_mesh(hairPart.data)   # fill it in from a Mesh
    verts=hairPart.data.vertices
    #verts.ensure_lookup_table()
    cnt+=1
    print( len(verts)," vertices" )
    # find the vertex closest to the "pin target" object location
    closestVertex = None
    distanceOld = 9999999.0
    selected_verts=0
    for v in verts:
        distanceNew = sqrt(
            (pinTargetLoc.x - (hairPart.location.x + v.co.x))**2 + 
            (pinTargetLoc.y - (hairPart.location.y + v.co.y))**2 + 
            (pinTargetLoc.z - (hairPart.location.z + v.co.z))**2)
        print( distanceNew )
        if ( distanceOld > distanceNew ):
            if ( closestVertex is not None ):
                closestVertex.select = False
            closestVertex = v
            print( closestVertex, "@", closestVertex.co )
            distanceOld = distanceNew

    # add 'closestVertex' to pinned group
    indexList = [ closestVertex.index ]  # vertex index list  of single closet item
    print( "closestVertex.index=", closestVertex.index )
    hairPart.vertex_groups.active_index=1
    pinnedGroup=hairPart.vertex_groups.get("pinned")
    pinnedGroup.add( indexList, 1.0, "ADD" )

    print("v count",selected_verts)
    print( "closestVertex.co=",closestVertex.co )
# end of script

I then selected all strands, and then Joined them into the Scalp, where I could then Select the "pinned" Vertex Group and see the result:

enter image description here

I can now use this Vertex Group as the Cloth -- Pin group to keep hair strands from flying away.

$\endgroup$

You must log in to answer this question.

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