def __setup_controls(self): self.up_vector = None for i in range(2): ctl = self.__create_control(self._side, self._moduleName, i, self._color, self.mod) if not i: nme = self._side + '_' + self._moduleName + "Up" self.up_vector = node.transform(name=nme, position=[1, 0, 0], parent=ctl.transform) if i: aim = node.aimConstraint(target=self.controls[0].transform, source=ctl.transform, aimVector=[0, -1, 0], upVector=[0, 0, 0], worldUpObject=self.up_vector, worldUpType='object') self.to_ihi.append(aim) attribute.lock_attributes(ctl.transform, ['r'], False, True) attribute.lock_n_hide(self.controls[0].transform, ['r'], True) self.controls.append(ctl) if self._mirror: self.__mirror_guides(ctl.transform, i) #-- create control chain self.__create_chain(self.controls)
def __setup_controls(self): """ Setup the controls properly """ #--- lock and hide unnecessary attributes of the controls attribute.lock_attributes([ self.control_down.transform, self.control_up.transform, self.control_mid.transform ], ['s', 'v'], True, False) attribute.lock_all([ self.control_down.group, self.control_up.group, self.control_mid.group ]) #--- pointConstraint the joint controls, #--- connect the joints' jontOrient and jointGrp scale transforms for jnt in range(len(self.jnt_grp)): node.pointConstraint(objA=self.jnt_ctl[jnt].transform, objB=self.jnt_grp[jnt], maintainOffset=False) goe.connectAttr(self.jnt_ctl[jnt].transform + '.s', self.jnt_grp[jnt] + '.s') #--- lock rotation and visibility attributes of the joint controls attribute.lock_attributes(self.jnt_ctl[jnt].transform, ['r', 'v']) #--- connect the globalScale of the main control with the scale one goe.connectAttr(self.control_main.transform + '.globalScale', self.control_main.transform + '.sx') goe.connectAttr(self.control_main.transform + '.globalScale', self.control_main.transform + '.sy') goe.connectAttr(self.control_main.transform + '.globalScale', self.control_main.transform + '.sz') #--- parent the global movement group under the main control cmds.parent(self.global_move, self.control_main.transform)
def parent(*args): """ @type args: *args @param args: specify nodes as you would do usually with maya cmds """ for i in args: assert i, "Please specify a valid child and a valid parent node" assert cmds.objExists(i), "Please specify existing children and parent" assert len(args) > 1, "Please specify a valid child and a valid parent node" #--- unlock the attributes attribute.lock_attributes(list(args[:-1]), ['t', 'r', 's'], False) cmds.parent(args) attribute.lock_attributes(list(args[:-1]), ['t', 'r', 's'])
def __cleanup(self, ): """ Cleanup the flexiPlane nodes """ #--- lock attributes on the controls attribute.lock_attributes( [self.control_up.transform, self.control_down.transform], ['ry', 'rz', 's']) attribute.lock_attributes(self.control_mid.transform, ['r', 's']) attribute.lock_attributes(self.control_main.transform, ['s', 'v']) if self._muscleSystem: attribute.lock_attributes(self.mus_ctl.transform, ['v']) #--- lock all nodes attribute.lock_all(self.main) attribute.lock_all(self.extra_nodes) attribute.lock_all(self.locator) attribute.lock_all(self.jnt_grp) attribute.lock_all(self.jnt) sel = cmds.ls('*GRP*', '*DEF*', '*AIM', '*PAC', '*PCN', '*OCN', '*SCN', '*CLS*', '*FOL*', '*LOC*', '*BLC', '*CND', '*MLT', '*CRV', '*RMV', '*DCM', '*tweak*', '*_Shape*', '*surface', '*NRB', '*BSP', 'makeNurbPlane*', '*FPCTLShape', '*CRVShape', '*ShapeShape', '*NRBShape', '*surfaceShape') for i in sel: attribute.lock_all(i) cmds.setAttr(i + '.ihi', 0) if self._hideControls: ctl = [ self.control_down.transform, self.control_main.transform, self.control_mid.transform, self.control_up.transform ] for i in ctl: attribute.hide(i) for i in self.jnt_ctl: attribute.hide(i.transform)
def parent(*args): """ @type args: *args @param args: specify nodes as you would do usually with maya cmds """ for i in args: assert i, "Please specify a valid child and a valid parent node" assert cmds.objExists(i), "Please specify existing children and parent" assert len( args) > 1, "Please specify a valid child and a valid parent node" #--- unlock the attributes attribute.lock_attributes(list(args[:-1]), ['t', 'r', 's'], False) cmds.parent(args) attribute.lock_attributes(list(args[:-1]), ['t', 'r', 's'])
def __create_ik_setup(self): """ Create an ikSingleSolver setup """ ik = tools.two_joint_ik(self.joints[0], self.joints[1], self.controls[1].transform) rev_ik = tools.two_joint_ik(self.rev_joints[1], self.rev_joints[0], self.controls[0].transform) #--- connect visibility of ikHandles with main group attribute.lock_attributes(ik, ['v'], False) attribute.lock_attributes(rev_ik, ['v'], False) cmds.connectAttr(self.mod_grp + '.showIkHandles', ik[0] + '.v') cmds.connectAttr(self.mod_grp + '.showIkHandles', rev_ik[0] + '.v') attribute.lock_attributes(ik, ['v']) attribute.lock_attributes(rev_ik, ['v'])
def lock(controlAttributes={}, lock=True, hide=True): """ @type controlAttributes: dict @param controlAttributes: specify a key(control) and value(list), ie. controlToTransform={'controlA:['t', 'sx',...]} @type lock: boolean @param lock: lock attributes @type hide: boolean @param hide: hide attributes """ if not controlAttributes: return for attr in controlAttributes.items(): key = attr[0] value = attr[1] msg = "lockAttrs: Key object does not exist: " + str(key) assert cmds.objExists(key), msg for v in value: msg = ("lockAttrs: Given key object and value do not exist: " + str(key) + "." + str(v)) assert (cmds.objExists(key + '.' + v)), msg attribute.lock_attributes(key, value, lock, hide)
def two_joint_ik(startJoint=None, endEffector=None, ikParent=None): """ @type startJoint: string @param startJoint: specify the startJoint @type endEffector: string @param endEffector: specify the endEffector @type ikParent: string @param ikParent: specify the parent of the ikHandle """ #--- startJoint assert startJoint, "Please specify an existing startJoint!" assert cmds.objExists(startJoint), "Please specify an existing startJoint!" #--- endEffector assert endEffector, "Please specify an existing endEffector!" assert cmds.objExists( endEffector), "Please specify an existing endEffector!" #--- endParent assert ikParent, "Please specify an existing parent for the ikHandle!" assert cmds.objExists(ikParent), "Please specify an existing parent node!" #--- create joint chain child = cmds.listRelatives(startJoint, type='transform') if not child or not child[0] == endEffector: attribute.lock_attributes(endEffector, ['t', 'r', 's'], False) cmds.parent(endEffector, startJoint) attribute.lock_attributes(endEffector, ['t', 'r', 's']) attribute.lock_attributes(startJoint, ['r'], False) #--- compose name ikname = ikParent.split('_')[0] + '_' + ikParent.split('_')[1] + '_IKH' ikeff = ikParent.split('_')[0] + '_' + ikParent.split('_')[1] + '_EFF' #--- create ikHandle ik = cmds.ikHandle(startJoint=startJoint, endEffector=endEffector, solver='ikSCsolver', name=ikname) eff = cmds.rename(ik[1], ikeff) ik.pop(1) ik.append(eff) #--- parent to ikParent cmds.parent(ik[0], ikParent) cmds.setAttr(ik[0] + '.t', 0, 0, 0) cmds.setAttr(ik[0] + '.r', 0, 0, 0) #--- cleanup for i in [ik[0], ik[1], 'ikSCsolver']: cmds.setAttr(i + '.ihi', 0) attribute.lock_all(i) return ik
def two_joint_ik(startJoint=None, endEffector=None, ikParent=None): """ @type startJoint: string @param startJoint: specify the startJoint @type endEffector: string @param endEffector: specify the endEffector @type ikParent: string @param ikParent: specify the parent of the ikHandle """ #--- startJoint assert startJoint, "Please specify an existing startJoint!" assert cmds.objExists(startJoint), "Please specify an existing startJoint!" #--- endEffector assert endEffector, "Please specify an existing endEffector!" assert cmds.objExists(endEffector), "Please specify an existing endEffector!" #--- endParent assert ikParent, "Please specify an existing parent for the ikHandle!" assert cmds.objExists(ikParent), "Please specify an existing parent node!" #--- create joint chain child = cmds.listRelatives(startJoint, type='transform') if not child or not child[0] == endEffector: attribute.lock_attributes(endEffector, ['t', 'r', 's'], False) cmds.parent(endEffector, startJoint) attribute.lock_attributes(endEffector, ['t', 'r', 's']) attribute.lock_attributes(startJoint, ['r'], False) #--- compose name ikname = ikParent.split('_')[0] + '_' + ikParent.split('_')[1] + '_IKH' ikeff = ikParent.split('_')[0] + '_' + ikParent.split('_')[1] + '_EFF' #--- create ikHandle ik = cmds.ikHandle(startJoint=startJoint, endEffector=endEffector, solver='ikSCsolver', name=ikname) eff = cmds.rename(ik[1], ikeff) ik.pop(1) ik.append(eff) #--- parent to ikParent cmds.parent(ik[0], ikParent) cmds.setAttr(ik[0] + '.t', 0, 0, 0) cmds.setAttr(ik[0] + '.r', 0, 0, 0) #--- cleanup for i in [ik[0], ik[1], 'ikSCsolver']: cmds.setAttr(i + '.ihi', 0) attribute.lock_all(i) return ik
def three_joint_ik(jointChain=[], ikParent=None, pvControl=None, pvGroup=None, offset=1): """ @type jointChain: list @param jointChain: specify three joints in a proper order. @type ikParent: string @param ikParent: specify the control to parent the ikHandle to @type pvControl: string @param pvControl: specify the poleVector control @type pvGroup: string @param pvGroup: specify the poleVector group """ #--- jointChain assert jointChain, "Please specify an existing startJoint!" if not pvControl: pvControl = cmds.createNode('transform') if not pvGroup: pvGroup = pvControl jointpos = list() #--- create joint chain for num, jnt in enumerate(jointChain): j = num + 1 pos = cmds.xform(jnt, query=True, translation=True, worldSpace=True) jointpos.append(pos) if not j == len(jointChain): attribute.lock_attributes(jointChain[j], ['t', 'r', 's', 'v']) child = cmds.listRelatives(jnt, type='transform') if not child or not child[0] == jointChain[j]: cmds.parent(jointChain[j], jnt) attribute.lock_attributes(jointChain[j], ['r'], False) attribute.lock_attributes(jnt, ['r'], False) #--- calculate the polevector position attribute.lock_n_hide(pvGroup, ['t', 'r'], True) pvpos = goemath.calculate_polevector(jointpos[0], jointpos[1], jointpos[2], offset) cmds.xform(pvGroup, translation=(pvpos.x, pvpos.y, pvpos.z), worldSpace=True) cmds.setAttr(pvGroup + '.r', 0, 0, 0) attribute.lock_n_hide(pvGroup, ['t', 'r']) #--- compose name ikname = ikParent.split('_')[0] + '_' + ikParent.split('_')[1] + '_IKH' ikeff = ikParent.split('_')[0] + '_' + ikParent.split('_')[1] + '_EFF' #--- create ikHandle ik = cmds.ikHandle(startJoint=jointChain[0], endEffector=jointChain[-1], solver='ikRPsolver', name=ikname) eff = cmds.rename(ik[1], ikeff) ik.pop(1) ik.append(eff) #--- create the poleVectorConstraint pvc = cmds.poleVectorConstraint(pvControl, ik[0])[0] #--- parent to ikParent cmds.parent(ik[0], ikParent) cmds.setAttr(ik[0] + '.t', 0, 0, 0) cmds.setAttr(ik[0] + '.r', 0, 0, 0) #--- cleanup for i in [ik[0], ik[1], 'ikRPsolver', pvc]: cmds.setAttr(i + '.ihi', 0) attribute.lock_all(i) return ik
def __constraint_flexiplane(self): """ Constraint the main control by specified nodes """ #--- check given flags if not self._constraintTo == [None, None]: msg = 'Specified node: ' + self._constraintTo[0] + 'does not exist!' assert cmds.objExists(self._constraintTo[0]), msg assert cmds.objExists(self._constraintTo[1]), msg #--- constraint the controls to proper positions pac = node.parentConstraint(objA=self._constraintTo, objB=self.control_main.transform, maintainOffset=False) pcn_down = node.pointConstraint(objA=self._constraintTo[0], objB=self.control_down.transform, maintainOffset=False) pcn_up = node.pointConstraint(objA=self._constraintTo[1], objB=self.control_up.transform, maintainOffset=False) cmds.delete(pac, pcn_down, pcn_up) #--- constraint the controls by given flag constraintType #--- parent = parentConstraint if self._constraintType == 'parent': node.parentConstraint(objA=self._constraintTo[0], objB=self.control_down.transform, suffix='PAC', maintainOffset=False) node.parentConstraint(objA=self._constraintTo[1], objB=self.control_up.transform, suffix='PAC', maintainOffset=False) #--- lock constraint attributes attribute.lock_attributes( [self.control_down.transform, self.control_up.transform], ['t', 'r']) #--- point = pointConstraint elif self._constraintType == 'point': node.pointConstraint(objA=self._constraintTo[0], objB=self.control_down.transform, suffix='PCN', maintainOffset=False) node.pointConstraint(objA=self._constraintTo[1], objB=self.control_up.transform, suffix='PCN', maintainOffset=False) #--- lock constraint attributes attribute.lock_attributes( [self.control_down.transform, self.control_up.transform], ['t']) #--- orient = orientConstraint elif self._constraintType == 'orient': node.orientConstraint(objA=self._constraintTo[0], objB=self.control_down.transform, suffix='OCN', maintainOffset=False) node.orientConstraint(objA=self._constraintTo[1], objB=self.control_up.transform, suffix='OCN', maintainOffset=False) #--- lock constraint attributes attribute.lock_attributes( [self.control_down.transform, self.control_up.transform], ['r'])
def __muscle_system(self): """ Create a simple muscle system based on sculptDeformers """ if not self._muscleSystem: return #--- check if specified mesh is a mesh if self._mesh: msg = 'Specified mesh: ' + str(self._mesh) + ' does not exist!' assert cmds.objExists(self._mesh), msg child = cmds.listRelatives(self._mesh, allDescendents=True) node_type = cmds.nodeType(child) msg = 'Specified mesh: ' + str(self._mesh) + ' is not a mesh!' assert node_type == 'mesh', msg if not self._muscles < 1: #--- create a nurbsPlane self.muscle_surface = cmds.nurbsPlane(degree=1, width=10, lengthRatio=0.2, patchesU=self._length, patchesV=1, axis=(0, 1, 0), name=self.name + 'Muscle_NRB')[0] #--- rotate the muscle surface goe.setAttr(self.muscle_surface + '.r', self._rotation) #--- parent the muscle surface under extra nodes cmds.parent(self.muscle_surface, self.extra_nodes) #--- create a follicle by the given amount of the muscles flag for i in range(self._muscles): i = i + 1 if i == 0: continue #--- MUSCLE FOLLICLE SETUP JUST SCULPT DEFORMER #--- create a follicle on the muscle plane mus_follicle = node.follicle(name=self.name + 'Muscle' + ` i `, suffix='FOL', parameterU=0, parameterV=0.5, parent=self.follicle_grp, show=False, lockAttr='parameterV') #--- connect the follicle with the muscle surface goe.connectAttr(self.muscle_surface + '.local', mus_follicle[1] + '.inputSurface') goe.connectAttr(self.muscle_surface + '.worldMatrix[0]', mus_follicle[1] + '.inputWorldMatrix') #--- connect the main control and the muscle follicle at = '.muscle' + ` i ` + 'Slide' goe.connectAttr(self.control_main.transform + at, mus_follicle[1] + '.parameterU') #--- NORMAL FOLLICLE SETUP, MUSCLE CTL DRIVES SCULPT #--- create a follicle on the normal surface norm_follicle = node.follicle(name=self.name + 'MuscleCtl' + ` i `, suffix='FOL', parameterU=0, parameterV=0.5, parent=self.follicle_grp, show=False, lockAttr='parameterV') #--- connect the follicle with the normal surface goe.connectAttr(self.surface + '.local', norm_follicle[1] + '.inputSurface') goe.connectAttr(self.surface + '.worldMatrix[0]', norm_follicle[1] + '.inputWorldMatrix') #--- connect the normal follicle scale attributes to the globalMovement group node.scaleConstraint(objA=self.global_move, objB=norm_follicle[0], maintainOffset=True) #--- create connections between the main control and the muscle follicle at = '.muscle' + ` i ` + 'Slide' goe.connectAttr(self.control_main.transform + at, norm_follicle[1] + '.parameterU') #--- SCULPT DEFORMER #--- create a control for the sculpt deformer and set it up nme = self._mod + self._name[0].upper( ) + self._name[1:] + 'Muscle' + ` i ` self.mus_ctl = controls.Control(side=self._side, name=nme, suffix='FPCTL', size=self._size + 0.1, shape=2, color=self._color, parent=norm_follicle[0]) #--- connect the size attr of the main control with the #--- scale of the muscle controls' group for axis in 'xyz': at = '.muscle' + ` i ` + 'Size' goe.connectAttr(self.control_main.transform + at, self.mus_ctl.group + '.s' + axis) #--- connect the visiblity of the control with the #--- muscle attr of the main control goe.connectAttr( self.control_main.transform + '.muscle' + ` i `, self.mus_ctl.transform + '.v') #--- create a sculpt deformer and parent it under the muscle follicle sculpt = deformer.sculpt(mod=self._mod, side=self._side, name=self._name + 'Muscle', suffix='DEF', geometry=self._mesh, dropoffDistance=0.14, parent=mus_follicle[0]) #--- CONNECTION MUSCLE CONTROL WITH SCULPT DEFORMER #--- connect the muscle size attr with the sculpt radius at = '.muscle' + ` i ` + 'Size' goe.connectAttr(self.control_main.transform + at, sculpt[1] + '.radius') attribute.lock_attributes(sculpt[0], ['s'], False) #--- connect the muscle controls scale with the sculpt one goe.connectAttr(self.mus_ctl.transform + '.s', sculpt[0] + '.s') #--- connect the muscle MaxDisplacement attr with the sculpt one at = '.muscle' + ` i ` + 'MaxDisplace' goe.connectAttr(self.control_main.transform + at, sculpt[2] + '.maximumDisplacement') #--- connect the muscle dropOff attr with the sculpt one at = '.muscle' + ` i ` + 'DropOff' goe.connectAttr(self.control_main.transform, sculpt[2] + '.dropoffDistance') #--- connect t and r of the sculpt with the muscle ctl goe.connectAttr(self.mus_ctl.transform + '.t', sculpt[0] + '.t') goe.connectAttr(self.mus_ctl.transform + '.r', sculpt[0] + '.r') #--- lock tx attribute of the muscle ctl attribute.lock_attributes(self.mus_ctl.transform, ['tx']) #--- set the sculpts' transform values to default goe.setAttr(sculpt[-1] + '.t', 0, 0, 0) goe.setAttr(sculpt[-1] + '.r', 0, 0, 0) attribute.lock_attributes(sculpt[-1], ['t', 'r']) cmds.setAttr(sculpt[0] + '.visibility', 0, lock=True) #--- COMPUTE PART #--- compute the steps to go to locate the cv's translateX position step = (10 / float(self._length)) off = (10 / float(self._length)) cv_pos = [[-5.0, 0.0, 0.0]] for i in range(self._length): res = -5 + step pos = [res, 0.0, 0.0] cv_pos.append(pos) step = +step + off #--- create the curves based on the computed position #--- and create clusters for each cv crv = cmds.curve(degree=2, point=cv_pos) mus_crv = cmds.rename(crv, self.name + 'Muscle_CRV') mus_cvs = cmds.ls(mus_crv + '.cv[*]', flatten=True) cmds.parent(mus_crv, self.extra_nodes) #--- create a matrix setup to connect the cvs with the control for i in range(len(mus_cvs)): dcm = node.decomposeMatrix(name=self.name + 'Muscle' + ` i `) if i == 0: goe.connectAttr( self.control_down.transform + '.worldMatrix[0]', dcm + '.inputMatrix') goe.connectAttr(dcm + '.outputTranslate', mus_crv + '.controlPoints[0]') elif i == (len(mus_cvs) - 1): goe.connectAttr( self.control_up.transform + '.worldMatrix[0]', dcm + '.inputMatrix') at = 'controlPoints[' + str(len(mus_cvs) - 1) + ']' goe.connectAttr(dcm + '.outputTranslate', mus_crv + at) else: goe.connectAttr( self.jnt_ctl[i - 1].transform + '.worldMatrix[0]', dcm + '.inputMatrix') at = '.controlPoints[' + ` i ` + ']' goe.connectAttr(dcm + '.outputTranslate', mus_crv + at)