cluster deform

50 views
Skip to first unread message

Abdelhalim abulmagd

unread,
Apr 18, 2024, 5:10:10 AMApr 18
to Python Programming for Autodesk Maya
how can i make cluster with the same orientation of the component
Screenshot 2024-04-18 110437.png

Marcelo

unread,
Apr 20, 2024, 2:27:53 PMApr 20
to Python Programming for Autodesk Maya
Follicle will be the easiest option I think, but you need non-overlapping UVs
Other than that, you could use a closestPointOnMesh, but you'll have to compose the matrix using cross products

Here's a an example of how you could implement the second option:

def cluster_on_vtx(vtx_ls=None, cleanup=True):
    if not vtx_ls:
        vtx_ls = cmds.ls(sl=True, fl=True)
   
    for vtx in vtx_ls:
        # Make sure it's a vertex
        if not cmds.filterExpand(vtx, selectionMask=31):
            continue
                   
        vtx_i = vtx.split('[')[-1].split(']')[0]
        mesh = cmds.polyListComponentConversion(vtx)[0]
        trs = cmds.listRelatives(mesh, parent=True)[0]
        pos = cmds.pointPosition(vtx)
        pos = [i - j for i, j in zip(pos, cmds.xform(trs, q=True, t=True, ws=True))]
   
        # Create temp closestPointOnMatrix
        tmp_cpom = cmds.createNode('closestPointOnMesh')
        cmds.setAttr(f'{tmp_cpom}.inPosition', *pos)
       
        # Create temp vectorProducts
        tmp_vp_x = cmds.createNode('vectorProduct')
        cmds.setAttr(f'{tmp_vp_x}.operation', 2)
        cmds.setAttr(f'{tmp_vp_x}.normalizeOutput', 1)
        tmp_vp_y = cmds.duplicate(tmp_vp_x)[0]
       
        # Create temp fourByFourMatrix
        tmp_fbf = cmds.createNode('fourByFourMatrix')
       
        # Connect Mesh
        cmds.connectAttr(f'{mesh}.outMesh', f'{tmp_cpom}.inMesh')
       
        # Connect normal output to fbf's Z vector
        for index, axis in enumerate('XYZ'):
            cmds.connectAttr(f'{tmp_cpom}.normal{axis}', f'{tmp_fbf}.in2{index}')
       
        # Get cross product of world Y against normal and connect to fbf's X vector
        cmds.setAttr(f'{tmp_vp_x}.input1Y', 1)
        for index, axis in enumerate('XYZ'):
            cmds.connectAttr(f'{tmp_cpom}.normal{axis}', f'{tmp_vp_x}.input2{axis}')
            cmds.connectAttr(f'{tmp_vp_x}.output{axis}', f'{tmp_fbf}.in0{index}')
           
        # Get cross product of X vector and normal and connect to fbf's Y vector
        for index, axis in enumerate('XYZ'):
            cmds.connectAttr(f'{tmp_cpom}.normal{axis}', f'{tmp_vp_y}.input1{axis}')
            cmds.connectAttr(f'{tmp_vp_x}.output{axis}', f'{tmp_vp_y}.input2{axis}')                  
            cmds.connectAttr(f'{tmp_vp_y}.output{axis}', f'{tmp_fbf}.in1{index}')
           
        # Connect potision to fbf
        for index, axis in enumerate('XYZ'):
            cmds.connectAttr(f'{tmp_cpom}.position{axis}', f'{tmp_fbf}.in3{index}')
       
           
        # Create multMatrix to compensate for trs's position
        tmp_mm = cmds.createNode('multMatrix')
        cmds.connectAttr(f'{tmp_fbf}.output', f'{tmp_mm}.matrixIn[0]')
        cmds.connectAttr(f'{trs}.worldMatrix[0]', f'{tmp_mm}.matrixIn[1]')
       
        # Create transform to drive the cluster
        clus_trs_zero = cmds.createNode('transform', name=f'{mesh}_{vtx_i}_clus_zero')
        clus_trs = cmds.createNode('transform', name=f'{mesh}_{vtx_i}_clus')
        cmds.parent(clus_trs, clus_trs_zero)
        cmds.xform(clus_trs_zero, m=cmds.getAttr(f'{tmp_mm}.matrixSum'), ws=True)
        clus = cmds.deformer(trs, type='cluster')[0]
        cmds.connectAttr(f'{clus_trs}.worldMatrix[0]', f'{clus}.matrix')
        cmds.setAttr(f'{clus}.bindPreMatrix', cmds.getAttr(f'{clus_trs}.parentInverseMatrix[0]'), type='matrix')
       
        if cleanup:
            to_del = [v for k, v in locals().items() if k.startswith('tmp_')]
            cmds.delete(reversed(to_del))

Abdelhalim abulmagd

unread,
Apr 28, 2024, 7:56:14 AMApr 28
to Python Programming for Autodesk Maya
This helped me thank you 
Reply all
Reply to author
Forward
0 new messages