make additional control using cluster

36 views
Skip to first unread message

Abdelhalim abulmagd

unread,
Apr 19, 2024, 1:18:10 PMApr 19
to Python Programming for Autodesk Maya
i try to make script that make additional control using cluster but i ran into a problem 
When I rotate the object after i create the cluster control , the Axis don't work well

please watch this video
https://youtu.be/ZyDfhcTOGhg

code:

import maya.cmds as cmds
import maya.mel as mel
import maya.OpenMaya as om
class Control():

    def __init__(self):
        orient = 1
        self.elements, self.weights = self._get_soft_selection()
       
        # get the currect tool selected
        deful_ctx = cmds.currentCtx()

        vtx = cmds.ls(sl=True)[0]
        self.obj = cmds.listRelatives(cmds.listRelatives(vtx, p=True), p=True)[0]

        # make cluster & delet weight
        cluster_name = self.get_name('cHandle_')
        self.cluster, cluster_handle = cmds.cluster(self.obj, n=cluster_name)
        cmds.select(self.obj, r=1)
        mel.eval(f'artSetToolAndSelectAttr( "artAttrCtx", "cluster.{self.cluster}.weights" )')
        self.curr_ctx = cmds.currentCtx() # cmds.setToolTo(self.curr_ctx)
        cmds.artAttrCtx(self.curr_ctx, selectedattroper='absolute', edit=True)
        cmds.artAttrCtx(self.curr_ctx, edit=True, value=0)
        cmds.artAttrCtx(self.curr_ctx, edit=True, clear=True)


        cmds.setToolTo(deful_ctx)


        # make locator & constrain it to vertx
        vtx_loc_name = self.get_name('vtx_loc_')
        vtx_loc = cmds.spaceLocator(n=vtx_loc_name)[0]
        cmds.select(vtx, vtx_loc, r=1)
        cmds.pointOnPolyConstraint(mo=False)


        vtx_posision = cmds.xform(vtx_loc, t=1,q=1, ws=1)
        cmds.xform(cluster_handle, a=True, ws=True, piv=vtx_posision)
        cluster_shape = cmds.listRelatives(cluster_handle, c=True, s=True)[0]
        cmds.setAttr(cluster_shape + '.origin', *vtx_posision)

        # create cluster group
        cluster_group_name = self.get_name('cluster_group_')
        cluster_group = cmds.group(n=cluster_group_name, em=True)
        cluster_handle  = cmds.parent(cluster_handle, cluster_group)[0]

        # create control & put the control into 3 group
        control_name = self.get_name('control_')

        points = [[0.0, 0.5, 0.0], [0.0, 0.46194, 0.1913415], [0.0, 0.3535535, 0.3535535], [0.0, 0.1913415, 0.46194], [0.0, 0.0, 0.5], [0.0, -0.1913415, 0.46194], [0.0, -0.3535535, 0.3535535], [0.0, -0.46194, 0.1913415], [0.0, -0.5, 0.0], [0.0, -0.46194, -0.1913415], [0.0, -0.3535535, -0.3535535], [0.0, -0.1913415, -0.46194], [0.0, 0.0, -0.5], [0.0, 0.1913415, -0.46194], [0.0, 0.3535535, -0.3535535], [0.0, 0.46194, -0.1913415], [0.0, 0.5, 0.0], [0.1913415, 0.46194, 0.0], [0.3535535, 0.3535535, 0.0], [0.46194, 0.1913415, 0.0], [0.5, 0.0, 0.0], [0.46194, -0.1913415, 0.0], [0.3535535, -0.3535535, 0.0], [0.1913415, -0.46194, 0.0], [0.0, -0.5, 0.0], [-0.1913415, -0.46194, 0.0], [-0.3535535, -0.3535535, 0.0], [-0.46194, -0.1913415, 0.0], [-0.5, 0.0, 0.0], [-0.46194, 0.1913415, 0.0], [-0.3535535, 0.3535535, 0.0], [-0.1913415, 0.46194, 0.0], [0.0, 0.5, 0.0], [0.0, 0.46194, -0.1913415], [0.0, 0.3535535, -0.3535535], [0.0, 0.1913415, -0.46194], [0.0, 0.0, -0.5], [-0.1913415, 0.0, -0.46194], [-0.3535535, 0.0, -0.3535535], [-0.46194, 0.0, -0.1913415], [-0.5, 0.0, 0.0], [-0.46194, 0.0, 0.1913415], [-0.3535535, 0.0, 0.3535535], [-0.1913415, 0.0, 0.46194], [0.0, 0.0, 0.5], [0.1913415, 0.0, 0.46194], [0.3535535, 0.0, 0.3535535], [0.46194, 0.0, 0.1913415], [0.5, 0.0, 0.0], [0.46194, 0.0, -0.1913415], [0.3535535, 0.0, -0.3535535], [0.1913415, 0.0, -0.46194], [0.0, 0.0, -0.5]]
        knots = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
        control = cmds.curve(n=control_name, p=points, k=knots,d=1)

        control_group_name = self.get_name('control_group_')
        control_group_01, control_group_02, control_group_03 = cmds.group(n=control_group_name, em=True), cmds.group(n=control_group_name, em=True), cmds.group(n=control_group_name, em=True)
        control_group_02 = cmds.parent(control_group_02, control_group_01)[0]
        control_group_03 = cmds.parent(control_group_03, control_group_02)[0]
        control = cmds.parent(control, control_group_03)[0]

        # ---
        if orient:
            # create match rotation group
            match_rotation_group_name = self.get_name('match_rotation_group_')
            match_rotation_group = cmds.group(n=match_rotation_group_name, em=True)

            mult_matrix_node = cmds.createNode('multMatrix')
            inverse_matrix_node = cmds.createNode('inverseMatrix')
           
            cmds.connectAttr( f'{match_rotation_group}.xformMatrix',  f'{mult_matrix_node}.matrixIn[0]', force=1)
            cmds.connectAttr( f'{self.obj}.worldMatrix',  f'{mult_matrix_node}.matrixIn[1]', force=1)
            cmds.connectAttr( f'{mult_matrix_node}.matrixSum',  f'{inverse_matrix_node}.inputMatrix', force=1)
            cmds.connectAttr('{0}.matrixSum'.format(mult_matrix_node), '{0}.preMatrix'.format(self.cluster))
            cmds.connectAttr('{0}.outputMatrix'.format(inverse_matrix_node), '{0}.postMatrix'.format(self.cluster))
            decompose_rotation = cmds.createNode('decomposeMatrix')
            cmds.connectAttr('{0}.matrixSum'.format(mult_matrix_node), '{0}.inputMatrix'.format(decompose_rotation))
            cmds.connectAttr('{0}.outputRotate'.format(decompose_rotation), '{0}.rotate'.format(control_group_02))


        # ---
        cmds.connectAttr(f'{vtx_loc}.translate', f'{control_group_02}.translate', f=True)

        cmds.connectAttr(f'{control}.translate', f'{cluster_handle}.translate', f=True)
        cmds.connectAttr(f'{control}.rotate', f'{cluster_handle}.rotate', f=True)
        cmds.connectAttr(f'{control}.scale', f'{cluster_handle}.scale', f=True)

        multiply_divide_node = cmds.createNode( 'multiplyDivide' )
        cmds.setAttr( f"{multiply_divide_node}.input2X", -1)
        cmds.setAttr( f"{multiply_divide_node}.input2Y", -1)
        cmds.setAttr( f"{multiply_divide_node}.input2Z", -1)

        cmds.connectAttr(f'{control}.translate', f'{multiply_divide_node}.input1', f=True)
        cmds.connectAttr(f'{multiply_divide_node}.output', f'{control_group_03}.translate', f=True)

        self.add_weight()

        cmds.setAttr(f'{vtx_loc}.v', 0)
        cmds.setAttr(f'{cluster_handle}.v', 0)

        system_group_name = self.get_name('system_group_')
       
        system_group = cmds.group(em=1, n=system_group_name)
        # cmds.parent(vtx_loc, control_group_01, cluster_handle, system_group)

        if orient:
            cmds.matchTransform(match_rotation_group, vtx_loc, rot=1)

        cmds.select(control, r=1)



    def _get_soft_selection(self):

        # Grab the soft selection
        selection = om.MSelectionList()
        soft_sel = om.MRichSelection()
        om.MGlobal.getRichSelection(soft_sel)
        soft_sel.getSelection(selection)
        dag_path = om.MDagPath()
        component = om.MObject()

        # Filter Defeats the purpose of the else statement
        iter_sel = om.MItSelectionList(selection, om.MFn.kMeshVertComponent)
        elements, weights = [], []
        while not iter_sel.isDone():
            iter_sel.getDagPath(dag_path, component)

            # Grab the parent of the shape node
            dag_path.pop()
            node = dag_path.fullPathName()
            fn_comp = om.MFnSingleIndexedComponent(component)
            vtx_str = node + '.vtx[{}]'

            for i in range(fn_comp.elementCount()):
                elements.append(vtx_str.format(fn_comp.element(i)))
                weights.append(fn_comp.weight(i).influence() if fn_comp.hasWeights() else 1.0)

            iter_sel.next()

        return elements, weights

    def add_weight(self):
        for i in range(len(self.elements)):
            cmds.percent(self.cluster, self.elements[i], v=self.weights[i])

    def get_name(self, name, resize=None):
        next_found = False
        next_available = 1

        while not next_found:

            obj_name = name + str(next_available)
           
            if cmds.objExists(obj_name):

                if resize:
                    if obj_name == self.ctl:
                        next_found = True
                next_available += 1

            else:
                next_found = True
           
        return obj_name



create = Control()

Reply all
Reply to author
Forward
0 new messages