def create_planar_locators(nLocators, length=10.0, name='test', size=1): root = pm.spaceLocator(name='%s_root' %name) root.add_shape(shape='double_cross', axis='+z', size=size) locators=[root] for i in range(nLocators): spacing = length / (nLocators - 1) tx = i * spacing locator = pm.spaceLocator(name='%s_locator_%d' %(name, i+1)) locator.getShape().localScale.set([size,size,size]) #locator.add_parent_group() pm.parent(locator, root) locator.translateX.set(tx) locators.append(locator) for i in range(2, len(locators)): pm.aimConstraint(locators[i], locators[i-1], mo=False, aimVector=[1,0,0], upVector=[0,0,1], worldUpType='objectrotation', worldUpVector = [0,0,1], worldUpObject=root) for locator in locators[1:]: locator.tz.lock() locator.rotate.lock() for locator in locators[1:-1]: locator.add_rotate_arrows(size=size) return locators
def MakeStabilizedNode(nodeName=None): ''' Very simple proc to generate a Stabilized node for raw MoCap tracking purposes... First selected node is used as the Aim axis, second selected is used as this aim's worldUp ''' RequiredMarkers = pm.ls(sl=True, l=True) AimAt = RequiredMarkers[0] WorldUpObj = RequiredMarkers[1] #pos = pm.xform(WorldUpObj, q=True, ws=True, t=True) Curve = pm.curve(ws=True, d=1, p=(0, 0, 0), k=0) pm.pointConstraint(RequiredMarkers, Curve) pm.aimConstraint((AimAt, Curve), weight=1, aimVector=(0, 0, 1), upVector=(0, 1, 0), worldUpType="object", worldUpObject=WorldUpObj) #Snap a curveKnot to the pivot of all referenceMarkers for node in RequiredMarkers: pm.curve(Curve, a=True, ws=True, p=(pm.xform(node, q=True, ws=True, t=True))) pm.curve(Curve, a=True, ws=True, p=(pm.xform(AimAt, q=True, ws=True, t=True))) return Curve
def alignSecCtlAlongXfos(ctl, prevXfo=None, nextXfo=None): ''' xAxis of ctl will always aim towards nextXfo, or away from prevXfo zAxis of ctl is used for upAxis ''' # add offsets autoOffset = secCtl.addOffset(ctl, 'child', '_autoAlign') manualOffset = secCtl.addOffset(ctl, 'child', '_manualAlign') # manualOffset uses ctl's rotations ctl.r >> manualOffset.r # autoOffset uses aim constraints if prevXfo and nextXfo: # have to blend between two xfos blendTwoAimConstraints(autoOffset, prevXfo, nextXfo) else: # direct aim constraint to either if prevXfo: pm.aimConstraint(prevXfo, autoOffset, mo=True, aim=(-1,0,0), u=(0,0,1), wut='objectrotation', wuo=ctl, wu=(0,0,1)) elif nextXfo: pm.aimConstraint(nextXfo, autoOffset, mo=True, aim=(1,0,0), u=(0,0,1), wut='objectrotation', wuo=ctl, wu=(0,0,1))
def generateTwistSystem(self, _twistEnds, _twistTarget, _invert=False): j1Trans = pm.PyNode(_twistEnds[0]).getTranslation(space='world') j2Trans = pm.PyNode(_twistEnds[-1]).getTranslation(space='world') twistAim = pm.datatypes.Vector(j2Trans - j1Trans) twistAim.normalize() twistDist = self.distanceBetween(j1Trans, j2Trans) twistDiv = twistDist / 5 i = 1 splitLocName = str(_twistEnds[0])[5:] twistJts = [] while i < 4: pos = j1Trans + (twistAim * (twistDiv * (i + 1))) newJt = pm.joint(n=splitLocName + '_twist_0' + str(i), p=pos) pm.parent(newJt, _twistEnds[0]) newJt.jointOrient.set([0, 0, 0]) twistJts.append(newJt) i += 1 pm.orientConstraint(twistJts[-1], twistJts[0], w=1, mo=0) pm.orientConstraint(_twistEnds[0], twistJts[0], w=2, mo=0) pm.orientConstraint(twistJts[-1], twistJts[1], w=2, mo=0) pm.orientConstraint(_twistEnds[0], twistJts[1], w=1, mo=0) if _invert: pm.aimConstraint(_twistEnds[-1], twistJts[-1], aim=(1, 0, 0), wuo=_twistTarget, wut='objectrotation', wu=(0, 1, 0)) else: pm.aimConstraint(_twistEnds[-1], twistJts[-1], aim=(-1, 0, 0), wuo=_twistTarget, wut='objectrotation', wu=(0, -1, 0))
def createConnector(self, pt1, pt2, radius=0.5): # create cylinder and align between pt1/pt2 base_name = pt1 _logger.debug('Connector base name is %s' % base_name) viz_shape = pm.cylinder(n=base_name + 'Connector') pm.pointConstraint([pt1, pt2], viz_shape[0], mo=0) pm.aimConstraint(pt2, viz_shape[0], weight=1, upVector=(0, 1, 0), worldUpType="vector", offset=(0, 0, 0), aimVector=(1, 0, 0), worldUpVector=(0, 1, 0)) viz_direction = pm.cone(n=base_name + 'Direction', r=3 * radius) viz_shape[0].t >> viz_direction[0].t viz_shape[0].r >> viz_direction[0].r # measure distance between dist_node = pm.createNode('distanceBetween', n=base_name + '_distanceBetween') pm.connectAttr(pt1 + '.worldMatrix[0]', dist_node + '.inMatrix1', f=True) pm.connectAttr(pt2 + '.worldMatrix[0]', dist_node + '.inMatrix2', f=True) _logger.debug('Distance between base name is %s' % base_name) # length divide_half = pm.createNode('multiplyDivide', n=base_name + '_distceBetween_multiplyDivide') divide_half.input2X.set(0.5) dist_node.distance >> divide_half.input1X divide_half.outputX >> viz_shape[0].scaleX # radius viz_shape[0].scaleZ.set(radius) viz_shape[0].scaleY.set(radius) return [viz_shape[0], viz_direction[0]]
def connectPrims( a=None, b=None ): # if a and/or b are none, use current selection try: if a ==None or b == None: a = pm.selected()[0] b = pm.selected()[1] # if current selection different from 2, print error message and do nothing else except: print "Current selection must have two objects!" # have the two objects aim at each other global Aim1 Aim1 = pm.aimConstraint( a, b) global Aim2 Aim2 = pm.aimConstraint( b, a) # create a curve with two points connecting the two prims myCurve = pm.curve(p=[(a.translate.get()), (b.translate.get())], degree=1) # creates the points at the location of the translate pivot (center of object) # create clusters for CVs cluster1 = pm.cluster(myCurve.cv[0]) # cluster for the first point of the myCurve cluster2 = pm.cluster(myCurve.cv[1]) # cluster for the second point of myCurve # Constrain the clusters to the points pm.pointConstraint( a, cluster1) pm.pointConstraint( b, cluster2) # rename all the objects so they relate to the their purpose pm.rename(a, 'ObjectA') pm.rename(b, 'ObjectB') pm.rename(Aim1, 'Aim1') pm.rename(Aim2, 'Aim2') pm.rename(myCurve, 'ConnectingLine')
def curveAim(crv, aimCrv, numJnts, mo=True, aimVector=(0,1,0), upVector=(0,1,0), worldUpType="vector", worldUpVector=(0,1,0)): '''Takes two curves, creates joints on the first and aims objects at the second. Args: crv (pm.nt.nurbsCurve): nurbs curve to generate things on aimCrv (pm.nt.nurbsCurve): nurbs curve to aim things to numJnts (int): number of joints to be generated other : all of the aim vector constraint settings Returns list(grp, list(joints)) Usage: curveAim(pm.ls(sl=True)[0], pm.ls(sl=True)[1], 10) ''' grp = pm.group(em=True, n=aimCrv+'AIMDRV_GRP') joints = rig_makeJointsAlongCurve("seatbeltDrive", crv, numJnts) for joint in joints: joint.setParent(w=True) pociOrig = atc.rig_getClosestPointNode(joint, crv) print pociOrig.parameter.get() poci = pm.nodetypes.PointOnCurveInfo(n=joint+"_POCI") aimCrv.getShape().attr("worldSpace[0]").connect(poci.inputCurve) poci.parameter.set(pociOrig.parameter.get()) loc = pm.group(em=True, n=joint+'AIMDRV_GRP', p=grp) poci.position.connect(loc.t) pm.aimConstraint(loc, joint, mo=mo, aimVector=aimVector, upVector=upVector, worldUpType=worldUpType, worldUpVector=worldUpVector) return [grp, joints]
def create_point_base(self, point, **kwargs): super(RigAim, self).create_point_base(point, **kwargs) root = self.create.group.point_base(point, type='world', name='root') aim = pm.duplicate(root)[0] self.name_convention.rename_name_in_format(aim, name='aim') pm.move(aim, 10, **{'move{}'.format(config.axis_order[0].upper()): True, 'objectSpace': True, 'relative': True}) aim.setParent(self.rig_system.kinematics) root.setParent(self.rig_system.kinematics) reset = self.create.group.point_base(root, type='inserted', name='reset') self.tip = reset self.aim = root reset_control, control = self.create.controls.point_base(aim, name='aim') reset_control.setParent(self.rig_system.controls) parent = kwargs.pop('parent', control) aim_vector = [0, 0, 0] aim_vector[config.axis_order[0]] = 1 up_vector = [0, 0, 0] up_vector[config.axis_order[1]] = 1 self.create.constraint.point(point, reset, mo=True) pm.aimConstraint(aim, root, aimVector=aim_vector, worldUpType='objectrotation', upVector=up_vector, worldUpObject=parent, worldUpVector=[0, 1, 0]) self.rm.align(root, reset_control, translate=False) pm.parentConstraint(control, aim) self.reset_controls.append(reset_control) self.controls.append(control)
def orient_joint(self, joint, aimAxis=[1, 0, 0], upAxis=[0, 0, 1], worldUpType="vector", worldUpVector=[0, 1, 0]): #joint should be pm.nt.Joint type if not isinstance(joint, pm.nt.Joint): raise TypeError("%s sholud be an instance of pm.nt.Joint Class" % joint) jointUnder = self.jointUnder(joint) if jointUnder is None: return 0 temporalGroup = DrawNode(Shape.transform, 'temporalGroup') pm.parent(jointUnder, temporalGroup.drawnNode) pm.setAttr(joint.jointOrient, (0, 0, 0)) if worldUpType == "object": aimConst = pm.aimConstraint(jointUnder, joint, aimVector=aimAxis, upVector=upAxis, worldUpType=worldUpType, worldUpObject=worldUpVector) elif worldUpType == "vector": aimConst = pm.aimConstraint(jointUnder, joint, aimVector=aimAxis, upVector=upAxis, worldUpType=worldUpType, worldUpVector=worldUpVector) pm.delete(aimConst) pm.parent(jointUnder, joint) pm.setAttr(joint.jointOrient, (pm.getAttr(joint.rotate))) pm.setAttr((joint.rotate), [0, 0, 0]) pm.delete(temporalGroup.drawnNode)
def addCurlJnt(side, finger): # create curl jnt baseJnt = pm.PyNode(side+finger+'_a_jnt') loc = pm.PyNode(baseJnt.replace('_a_jnt', 'Cup_loc')) parJnt = baseJnt.getParent() # orient loc so x is aimed to baseJnt if '_rt' in side: temp_con = pm.aimConstraint(baseJnt, loc, aim=(-1,0,0), u=(0,0,1), wuo=parJnt, wut='objectrotation') else: temp_con = pm.aimConstraint(baseJnt, loc, aim=(1,0,0), u=(0,0,1), wuo=parJnt, wut='objectrotation') pm.delete(temp_con) # create jnt pm.select(cl=True) curlJnt = pm.joint(n=side+finger+'Cup_jnt') curlJnt.radius.set(baseJnt.radius.get()) mat = loc.getMatrix(ws=True) curlJnt.setMatrix(mat, ws=True) parJnt | curlJnt pm.makeIdentity(curlJnt, r=True, a=True) # find offset matrix for baseJnt currMat = baseJnt.getMatrix() offMat = currMat * curlJnt.getMatrix().inverse() txOffset = offMat.translate[0] # change parent for baseJnt curlJnt | baseJnt txMd = baseJnt.tx.inputs()[0] txMd.input2X.set(txOffset) return curlJnt
def make_stabilized_node(nodeName=None, centered=True): ''' Very simple proc to generate a Stabilized node for raw MoCap tracking purposes... First selected node is used as the Aim axis, second selected is used as this aim's worldUp ''' RequiredMarkers = pm.ls(sl=True, l=True) #pos = pm.xform(WorldUpObj, q=True, ws=True, t=True) curve = pm.curve(ws=True, d=1, p=(0, 0, 0), k=0) if centered: AimAt = RequiredMarkers[0] WorldUpObj = RequiredMarkers[1] pm.pointConstraint(RequiredMarkers, curve) else: AimAt = RequiredMarkers[1] WorldUpObj = RequiredMarkers[2] pm.pointConstraint(RequiredMarkers[0], curve) pm.aimConstraint((AimAt, curve), weight=1, aimVector=(0, 0, 1), upVector=(0, 1, 0), worldUpType="object", worldUpObject=WorldUpObj) #Snap a curveKnot to the pivot of all referenceMarkers for node in RequiredMarkers: pm.curve(curve, a=True, ws=True, p=(pm.xform(node, q=True, ws=True, t=True))) pm.curve(curve, a=True, ws=True, p=(pm.xform(AimAt, q=True, ws=True, t=True))) return curve
def AlignBindNode(self, **kws): ''' Overwrite the default behaviour: Align the newly made BindNode as required for this bind ''' #Parent the BindNode/UpVector Object to the upVectorParent Node #Parent the AimLocator Object to the Source node -used to modify the AimPoint pm.parent(self.BindNode['Root'], self.upVectorParent) pm.parent(self.BindNode['Up'], self.upVectorParent) pm.parent(self.BindNode['AimOffset'], self.SourceNode) #self.BindNode['Root'].scale.set(self.Settings.BaseScale,self.Settings.BaseScale,self.Settings.BaseScale) self.BindNode['Main'].rotateOrder.set(self.SourceNode.rotateOrder.get()) self.BindNode['Root'].rotateOrder.set(self.DestinationNode.rotateOrder.get()) #Aim Alignment pm.aimConstraint(self.BindNode['AimOffset'], self.BindNode['Root'], aimVector=(0,1,0),upVector=(0,0,1),\ worldUpType="object",worldUpObject=self.BindNode['Up']) #Positional Alignment pm.delete(pm.pointConstraint(self.SourceNode, self.BindNode['AimOffset'])) pm.makeIdentity(self.BindNode['AimOffset'], apply=True, t=1, r=1, s=0) pm.delete(pm.pointConstraint(self.upVectorParent, self.BindNode['Root'])) pm.makeIdentity(self.BindNode['Root'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.upVectorParent, self.BindNode['Up'])) pm.makeIdentity(self.BindNode['Up'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.DestinationNode, self.BindNode['Root'])) #Rotate Alignment pm.delete(pm.orientConstraint(self.DestinationNode, self.BindNode['Main']))
def align_bind_node(self, **kws): ''' Overwrite the default behaviour: Align the newly made BindNode as required for this bind ''' # Parent the BindNode/UpVector Object to the upVectorParent Node # Parent the AimLocator Object to the Source node -used to modify the AimPoint pm.parent(self.BindNode['Root'], self.upVectorParent) pm.parent(self.BindNode['Up'], self.upVectorParent) pm.parent(self.BindNode['AimOffset'], self.sourceNode) # self.BindNode['Root'].scale.set(self.settings.base_scale,self.settings.base_scale,self.settings.base_scale) self.BindNode['Main'].rotateOrder.set(self.sourceNode.rotateOrder.get()) self.BindNode['Root'].rotateOrder.set(self.destinationNode.rotateOrder.get()) # Aim Alignment pm.aimConstraint(self.BindNode['AimOffset'], self.BindNode['Root'], aimVector=(0, 1, 0), upVector=(0, 0, 1), worldUpType="object", worldUpObject=self.BindNode['Up']) # Positional Alignment pm.delete(pm.pointConstraint(self.sourceNode, self.BindNode['AimOffset'])) pm.makeIdentity(self.BindNode['AimOffset'], apply=True, t=1, r=1, s=0) pm.delete(pm.pointConstraint(self.upVectorParent, self.BindNode['Root'])) pm.makeIdentity(self.BindNode['Root'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.upVectorParent, self.BindNode['Up'])) pm.makeIdentity(self.BindNode['Up'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.destinationNode, self.BindNode['Root'])) # Rotate Alignment pm.delete(pm.orientConstraint(self.destinationNode, self.BindNode['Main']))
def connectCtrls(): ctrls = pm.ls(sl=1) masterGrp = groupTools.makeGroup(name='wingCtrlsConnect') coordsList = [] midDrvLocs = [] holdDrvLocs = [] mdCtrlsCoord = vtxWalk.bbox(ctrls)['globalPvt'] middle = controlTools.cntrlCrv(name='wingCtrlsConnect_mid_loc', coords=(mdCtrlsCoord, (0, 0, 0), (1, 1, 1)), cntrlSulfix='', parent=masterGrp, icone='null') tempConstraint = pm.pointConstraint(ctrls[0], ctrls[1], middle, mo=0) pm.delete(tempConstraint) pm.parentConstraint(ctrls[0].getParent().getParent(), ctrls[1].getParent().getParent(), middle, mo=1, sr=['x', 'y', 'z']) pm.aimConstraint(ctrls[0].getParent().getParent(), middle, wut='scene', mo=0) orientMiddle = pm.xform(middle, q=1, ro=1, ws=1) for ctrl in ctrls: coord = vtxWalk.bbox(ctrl)['globalPvt'] coordsList.append(coordsList) midLoc = controlTools.cntrlCrv(name=ctrl + '_mid_drv_loc', coords=(coord, (0, 0, 0), (1, 1, 1)), cntrlSulfix='', parent=middle, icone='null') midDrvLocs.append(midLoc) holdLoc = controlTools.cntrlCrv(name=ctrl + '_hold_drv_loc', coords=(coord, orientMiddle, (1, 1, 1)), cntrlSulfix='', parent=masterGrp, icone='null') holdDrvLocs.append(holdLoc) pm.parentConstraint(ctrl.getParent().getParent(), holdLoc, mo=1) pm.addAttr(ctrl, ln='autoConnect', dv=0.8, min=0, max=1, k=1) drvPointConstraint = pm.pointConstraint(midLoc, holdLoc, ctrl.getParent(), mo=1) #drvOrientConstraint = pm.orientConstraint(middle, holdLoc, ctrl.getParent(), mo=1) revNode = pm.createNode('reverse', n='wingCtrlsConnect_rev') ctrl.autoConnect >> revNode.inputX pm.connectAttr(ctrl.autoConnect, drvPointConstraint + '.' + midLoc + 'W0') pm.connectAttr(revNode.outputX, drvPointConstraint + '.' + holdLoc + 'W1')
def ctrlAimConstraint(): legsRootCtrl = pm.ls('*Leg*_1_ctrl') for ctrl in legsRootCtrl: pm.select(cl=1) aimposGrp = ctrl.getParent() aimCtrl = pm.ls(ctrl.name().replace('ctrl', 'aim_ctrl'))[0] pm.aimConstraint(aimCtrl, aimposGrp, mo=1) # aimConstraint -mo -weight 1 -aimVector 1 0 0 -upVector 0 1 1 -worldUpType "vector" -worldUpVector 0 1 0;
def aimConstraintRename(sels): if len(sels) >= 3 or len(sels) <= 1: pm.error('Please select two') part = sels[1].split("_") renameConstraint = '_'.join(['amc', part[1], part[2], part[3]]) pm.aimConstraint(sels[0], sels[1], n=renameConstraint, mo=True, w=1)
def FKIK_query_guide_orient(self, *args): print 'Querying the rotations of the guides which were placed.' POS_list = self.FKIK_query_guide_translation() # TODO: # Replace all this code with something a little # more elegant. # Likely something with OpenMaya for querying the # actual vectors and orientations of the objects # in world space? # Using cross products to determine the correct # planar relationships between guide positions. A_LOC = pm.spaceLocator() B_LOC = pm.spaceLocator() C_LOC = pm.spaceLocator() if self.debugging: print 'Created:', A_LOC, B_LOC, C_LOC A_LOC.setTranslation(POS_list[0]) B_LOC.setTranslation(POS_list[1]) C_LOC.setTranslation(POS_list[2]) A_orient = pm.aimConstraint(B_LOC, A_LOC, aimVector=[1, 0, 0], upVector=[0, 1, 0], worldUpType='object', worldUpObject=C_LOC) B_orient = pm.aimConstraint(C_LOC, B_LOC, aimVector=[1, 0, 0], upVector=[0, 1, 0], worldUpType='object', worldUpObject=A_LOC) C_orient = pm.aimConstraint(A_LOC, C_LOC, aimVector=[-1, 0, 0], upVector=[0, -1, 0], worldUpType='object', worldUpObject=B_LOC) A_value = A_LOC.getRotation() B_value = B_LOC.getRotation() C_value = C_LOC.getRotation() if not self.debugging: pm.delete(A_orient, B_orient, C_orient, A_LOC, B_LOC, C_LOC) else: print( 'Successfully completed the creation and query of guide orientation' ) print A_value, B_value, C_value return [A_value, B_value, C_value]
def build_stack(self, stack, aim_target=None, **kwargs): nomenclature_rig = self.get_nomenclature_rig() # Build an aim node in-place for performance # This separated node allow the joints to be driven by the avars. aim_grp_name = nomenclature_rig.resolve('lookgrp') aim_grp = pymel.createNode('transform', name=aim_grp_name) aim_node_name = nomenclature_rig.resolve('looknode') aim_node = pymel.createNode('transform', name=aim_node_name) aim_node.setParent(aim_grp) aim_target_name = nomenclature_rig.resolve('target') aim_target = pymel.createNode('transform', name=aim_target_name) aim_target.setParent(aim_grp) self.target = aim_target # Build an upnode for the eyes. # I'm not a fan of upnodes but in this case it's better to guessing the joint orient. aim_upnode_name = nomenclature_rig.resolve('upnode') aim_upnode = pymel.createNode('transform', name=aim_upnode_name) # aim_upnode.setParent(self.grp_rig) pymel.parentConstraint(aim_grp, aim_upnode, maintainOffset=True) pymel.aimConstraint(aim_target, aim_node, maintainOffset=True, aimVector=(0.0, 0.0, 1.0), upVector=(0.0, 1.0, 0.0), worldUpObject=aim_upnode, worldUpType='object' ) # Position objects aim_grp.setParent(self._grp_offset) # todo: add begin , end property aim_grp.t.set(0,0,0) aim_grp.r.set(0,0,0) jnt_tm = self.jnt.getMatrix(worldSpace=True) jnt_pos = jnt_tm.translate aim_upnode_pos = pymel.datatypes.Point(0,1,0) + jnt_pos aim_upnode.setTranslation(aim_upnode_pos, space='world') aim_target_pos = pymel.datatypes.Point(0,0,1) + jnt_pos aim_target.setTranslation(aim_target_pos, space='world') pymel.parentConstraint(aim_node, stack, maintainOffset=True) # Convert the rotation to avars to additional values can be added. util_decomposeMatrix = libRigging.create_utility_node('decomposeMatrix', inputMatrix=aim_node.matrix) libRigging.connectAttr_withBlendWeighted(util_decomposeMatrix.outputTranslateX, self.attr_lr) libRigging.connectAttr_withBlendWeighted(util_decomposeMatrix.outputTranslateY, self.attr_ud) libRigging.connectAttr_withBlendWeighted(util_decomposeMatrix.outputTranslateZ, self.attr_fb) libRigging.connectAttr_withBlendWeighted(util_decomposeMatrix.outputRotateY, self.attr_yw) libRigging.connectAttr_withBlendWeighted(util_decomposeMatrix.outputRotateX, self.attr_pt) libRigging.connectAttr_withBlendWeighted(util_decomposeMatrix.outputRotateZ, self.attr_rl)
def directPlacementMode(card): assert len(card.joints) == 3 grp = group(em=True, n='DirectPlacement_Deletable') ctrls = [] for bpj in card.joints: ctrl = tempWidget() pdil.dagObj.matchTo(ctrl, bpj) ctrls.append(ctrl) ctrl.setParent(grp) base, up, aim = ctrls aimLoc = spaceLocator() aimLoc.setParent(aim) aimLoc.t.set(0, 0, 0) baseLoc = spaceLocator() baseLoc.setParent(base) baseLoc.t.set(0, 0, 0) dist = distanceDimension(baseLoc, aimLoc) dist.getParent().setParent(grp) hide(dist) pointConstraint(base, card, mo=True) aimConstraint(aim, card, wut='object', wuo=up, aim=[0, -1, 0], u=[0, 0, -1], mo=True) # save base dimension # current dimesion / base dimension # multiply x, z by card's existing scale dist.addAttr('baseDist', at='double', dv=dist.distance.get()) scaled = pdil.math.divide(dist.distance, dist.baseDist) mult = createNode('multiplyDivide') scaled >> mult.input1X scaled >> mult.input1Y scaled >> mult.input1Z mult.input2Y.set(card.sy.get()) mult.input2Z.set(card.sz.get()) mult.outputY >> card.sy mult.outputZ >> card.sz pointConstraint(up, card.joints[1], sk='x')
def doGuide(self, **kwargs): self.__dict__.update(kwargs) displaySetup = self.moveallGuideSetup.copy() cntrlName = displaySetup['nameTempl'] + self.guideSulfix if pm.objExists(cntrlName): pm.delete(cntrlName) self.guideMoveall = controlTools.cntrlCrv(name=cntrlName, hasZeroGrp=False, cntrlSulfix='', **displaySetup) if not pm.objExists('GUIDES'): pm.group(self.guideMoveall, n='GUIDES') else: pm.parent(self.guideMoveall, 'GUIDES') self.startGuide = self.createCntrl('startGuide') self.midGuide = self.createCntrl('midGuide') self.endGuide = self.createCntrl('endGuide') pm.parent(self.startGuide, self.midGuide, self.endGuide, self.guideMoveall) if self.lastJoint: self.lastGuide = self.createCntrl('lastGuide') pm.parent(self.lastGuide, self.endGuide) self.setCntrl(self.lastGuide, 'last', space='object') self.setCntrl(self.startGuide, 'start', space='object') self.setCntrl(self.midGuide, 'mid', space='object') self.setCntrl(self.endGuide, 'end', space='object') arrow = controlTools.cntrlCrv(obj=self.startGuide, name=self.name + 'PlaneDir', icone='seta', size=.35, color=(0, 1, 1)) arrow.template.set(1) arrow.getParent().setParent(self.startGuide) pm.aimConstraint(self.endGuide, arrow, weight=1, aimVector=(1, 0, 0), upVector=(0, 0, -1), worldUpObject=self.midGuide, worldUpType='object') self.setCntrl(self.guideMoveall, 'moveall', space='world') pm.addAttr(self.guideMoveall, ln='limbDict', dt='string') # todo implementar funcao de exportar o dict self.guideMoveall.limbDict.set(json.dumps(self.exportDict()))
def create_jointChain( IdName = 'joint', inputCurve = pm.selected(), orientation = 'xyz' ): # get number of CVs on InputCurve numberOfCvs = pm.getAttr( inputCurve[0] + '.cp',s=1 ) # create joints on world space cv locations Jnts = [] for i in range(0, numberOfCvs): pm.select( clear = True ) currentCvPos = pm.pointPosition( inputCurve[0].cv[i], w=1 ) Jnt = pm.joint( name = '_'.join( ['bn', IdName, str( i+1 )] ) ) pm.xform( Jnt, t = currentCvPos ) Jnts.append( Jnt ) # create end joint pm.select( clear = True ) endJntPos = 0.1 * ( pm.getAttr( Jnts[len(Jnts)-1].translate ) - pm.getAttr( Jnts[len(Jnts)-2].translate ) ) + pm.getAttr( Jnts[len(Jnts)-1].translate ) endJnt = pm.joint( name = 'be_' + IdName, position = endJntPos, a = True ) Jnts.append( endJnt ) # set aim and orientation vectors, always yup aimDict = {} aimDict[orientation[0]] = 1 aimDict[orientation[1]] = 0 aimDict[orientation[2]] = 0 aimVec = ( aimDict['x'], aimDict['y'], aimDict['z'] ) orientDict = {} orientDict[orientation[0]] = 0 orientDict[orientation[1]] = 0 orientDict[orientation[2]] = 1 orientVec = ( orientDict['x'], orientDict['y'], orientDict['z'] ) # orient first joint JntAimConstrain = pm.aimConstraint( Jnts[1], Jnts[0], aimVector = aimVec, upVector = (0,1,0), worldUpType = "scene" ) pm.delete( JntAimConstrain ) Jnts[0].jointOrient.set( Jnts[0].rotate.get() ) Jnts[0].rotate.set( 0,0,0 ) # orient middle joints for i in range( 1, len( Jnts ) - 1 ): JntAimConstrain = pm.aimConstraint( Jnts[i+1], Jnts[i], aimVector = aimVec, upVector = orientVec, worldUpType = "objectrotation", worldUpVector = orientVec, worldUpObject = Jnts[i-1] ) pm.delete( JntAimConstrain ) Jnts[i].jointOrient.set( Jnts[i].rotate.get() ) Jnts[i].rotate.set( 0,0,0 ) # orient last joint Jnts[len( Jnts ) -1 ].jointOrient.set( Jnts[len( Jnts ) -2 ].jointOrient.get() ) # parent joints for i in range( 1, len( Jnts ) ): pm.parent( Jnts[i], Jnts[i-1], absolute = True) pm.select( Jnts[0] ) print('Successfully created and oriented joint-chain. Continuing...') return Jnts
def run(self, aim_this=None, at_this=None, up_target=None, flip_aim=False, flip_up=False): aim_this = aim_this or self.options.aim_this at_this = at_this or self.options.at_this up_target = up_target or self.options.up_target selection_list = pm.ls(sl=True) if len(selection_list) == 2: aim_this = selection_list[0] at_this = selection_list[1] elif len(selection_list) == 3: aim_this = selection_list[0] at_this = selection_list[1] up_target = selection_list[2] flip_aim = flip_aim or self.options.flip_aim flip_up = flip_up or self.options.flip_up if flip_aim: aim_vector = (-1, 0, 0) else: aim_vector = (1, 0, 0) if flip_up: up_vector = (0, 0, -1) else: up_vector = (0, 0, 1) scene_up = "scene" object_up = "object" if up_target: # aim with up target as upvector temp_constraint = pm.aimConstraint( at_this, aim_this, aimVector=aim_vector, upVector=up_vector, worldUpType=object_up, worldUpObject=up_target, ) else: # aim with assumed scene as upvector temp_constraint = pm.aimConstraint( at_this, aim_this, aimVector=aim_vector, upVector=up_vector, worldUpType=scene_up, ) pm.delete(temp_constraint)
def curveAimBelt(module, crv, aimCrv, numJnts, mo=True, aimVector=(0,1,0), upVector=(0,1,0), worldUpType="vector", worldUpVector=(0,1,0)): '''Takes two curves, creates joints on the first and aims objects at the second. Args: crv (pm.nt.nurbsCurve): nurbs curve to generate things on aimCrv (pm.nt.nurbsCurve): nurbs curve to aim things to numJnts (int): number of joints to be generated other : all of the aim vector constraint settings Returns list(grp, list(joints)) Usage: curveAimBelt("path", pm.ls(sl=True)[0], pm.ls(sl=True)[1], 40) ''' grp = pm.group(em=True, n=module+'_GRP') aimgrp = pm.group(em=True, n=module+'_AIMDRV_GRP', p=grp) joints = rig_makeJointsAlongCurve(module+"Drive", crv, numJnts) ikJoints = rig_makeJointsAlongCurve(module+"IK", crv, numJnts) skelgrp = pm.group(em=True, n=module+'Skeleton_GRP', p=grp) ikskelgrp = pm.group(em=True, n=module+'ikJNT_GRP', p=skelgrp) jntgrp = pm.group(em=True, n=module+'JNT_GRP', p=skelgrp) clstrGrp = pm.group(em=True, n=module+'Clusters_GRP', p=grp) crvGrp = pm.group(em=True, n=module+'Curves_GRP', p=grp) for joint,ikJoint in zip(joints,ikJoints): joint.setParent(jntgrp) pociResult = rig_getClosestPointAndPositionOnCurve(joint, crv) pociResult[2].setParent(aimgrp) pociOrig = pociResult[0] poci = pm.nodetypes.PointOnCurveInfo(n=joint+"_POCI") aimCrv.getShape().attr("worldSpace[0]").connect(poci.inputCurve) pociOrig.parameter.connect(poci.parameter) loc = pm.spaceLocator( n=joint+'AIMDRV_GRP' ) loc.setParent(aimgrp) poci.position.connect(loc.t) pm.pointConstraint(ikJoint, joint, mo=True) pm.aimConstraint(loc, joint, mo=mo, aimVector=aimVector, upVector=upVector, worldUpType=worldUpType, worldUpVector=worldUpVector) ikHandle=pm.ikHandle(sj=ikJoints[0], ee=ikJoints[-1], sol='ikSplineSolver', c=crv, ccv=False, rtm=False)[0] origClusters = rig_clusterCurve(crv, ends=True) offsetClusters = rig_clusterCurve(aimCrv, ends=True) for clstr, oClstr in zip(origClusters, offsetClusters): pm.parentConstraint(clstr[1], oClstr[1], mo=True) oClstr[1].visibility.set(0) clstr[1].setParent(clstrGrp) oClstr[1].setParent(clstrGrp) ikJoints[0].setParent(ikskelgrp) ikskelgrp.visibility.set(0) crvGrp.visibility.set(0) crv.setParent(crvGrp) aimCrv.setParent(crvGrp) ikHandle.setParent(ikskelgrp) aimgrp.inheritsTransform.set(0) return [grp, joints]
def aimDeserialize(obj, data): # type: (PyNode, Dict) -> None # If the world up object is absent, remove it entirely. kwargs = copy.deepcopy(data) if not kwargs['wuo']: del kwargs['wuo'] else: kwargs['wuo'] = add.findFromIds(kwargs['wuo']) targets, reformattedKwargs = _constraintDeserialize(obj, kwargs) aimConstraint(targets, obj, mo=True, **reformattedKwargs)
def reorientGuides(self): for i in range(len(self.guidesList)-1): guidePos = pm.xform(self.guidesList[i].name,q=1,rp=1,ws=1) self.guidesList[i].guideGrp.setPivots(guidePos,worldSpace=1) tempAim = pm.aimConstraint(self.guidesList[i+1].name,self.guidesList[i].guideGrp,offset = [0,0,0],aimVector = [1,0,0],upVector=[0,1,0],worldUpType='scene') pm.delete(tempAim) guidePos = pm.xform(self.guidesList[-1].name,q=1,rp=1,ws=1) self.guidesList[-1].guideGrp.setPivots(guidePos,worldSpace=1) tempAim = pm.aimConstraint(self.guidesList[-2].name,self.guidesList[-1].guideGrp,offset = [0,0,0],aimVector = [-1,0,0],upVector=[0,1,0],worldUpType='scene') pm.delete(tempAim)
def test_assertAimingAt(self): a = pm.group(empty=1) b = pm.group(empty=1) pm.move(3, 3, 3, b, a=1) self.assertFalse(transforms.assertAimingAt(a, b, 'x')) pm.aimConstraint(b, a) self.assertFalse(transforms.assertAimingAt(a, b, 'y')) self.assertFalse(transforms.assertAimingAt(a, b, 'z')) self.assertTrue(transforms.assertAimingAt(a, b, 'x'))
def test_assertAimingAt(self): a = pm.group(empty=1) b = pm.group(empty=1) pm.move(3, 3, 3, b, a=1) self.assertFalse(transforms.assertAimingAt(a, b, "x")) pm.aimConstraint(b, a) self.assertFalse(transforms.assertAimingAt(a, b, "y")) self.assertFalse(transforms.assertAimingAt(a, b, "z")) self.assertTrue(transforms.assertAimingAt(a, b, "x"))
def create_radian_trigger(prefix): prefix = ("%s_radianTrigger") %prefix display = pm.group(empty=True, name="%s_display" %prefix) display.overrideEnabled.set(1) display.overrideDisplayType.set(2) grp = pm.group(empty=True, name="%s_grp" %prefix) loc = pm.spaceLocator(name = "%s_target" %prefix) pm.addAttr(loc, at='double', ln="radical", k=True) pm.addAttr(loc, at='double', ln="angle", k=True) pos = pm.spaceLocator(name = "%s_pos" %prefix) loc.ty.set(1) loc.tz.set(1) pos.tz.set(1) radical_exp = '%s.radical = rad_to_deg( atan2( %s.translateY , %s.translateX ) )' %(loc.name(), loc.name(), loc.name()) angle_exp = "%s.angle = rad_to_deg( acos( %s.translateZ / (sqrt( pow(%s.translateX, 2) + pow(%s.translateY, 2) + pow(%s.translateZ, 2) ) ) ) )" %(loc.name(), loc.name(), loc.name(), loc.name(), loc.name()) pm.expression( o=loc, s= radical_exp, name="%s_radical_exp" %prefix) pm.expression( o=loc, s= angle_exp, name="%s_angle_exp" %prefix) planer_curve = "curve -d 1 -p 0 0 0 -p -1 0 0 -p -0.965926 0.258819 0 -p -0.765926 0.258819 0 -p -0.865926 0.258819 0 -p -0.865926 0.358819 0 -p -0.865926 0.158819 0 -p -0.865926 0.258819 0 -p -0.965926 0.258819 0 -p -0.866025 0.5 0 -p -0.707107 0.707107 0 -p -0.353553 0.353553 0 -p -0.707107 0.707107 0 -p -0.5 0.866025 0 -p -0.258819 0.965926 0 -p 0 1 0 -p 0 0.5 0 -p 0 1 0 -p 0.258819 0.965926 0 -p 0.5 0.866025 0 -p 0.707107 0.707107 0 -p 0.353553 0.353553 0 -p 0.707107 0.707107 0 -p 0.866025 0.5 0 -p 0.965926 0.258819 0 -p 1 0 0 -p 0.5 0 0 -p 1 0 0 -p 0.965926 -0.258819 0 -p 0.866025 -0.5 0 -p 0.707107 -0.707107 0 -p 0.353553 -0.353553 0 -p 0.707107 -0.707107 0 -p 0.5 -0.866025 0 -p 0.258819 -0.965926 0 -p 0 -1 0 -p 0 -0.5 0 -p 0 -1 0 -p -0.258819 -0.965926 0 -p -0.5 -0.866025 0 -p -0.707107 -0.707107 0 -p -0.353553 -0.353553 0 -p -0.707107 -0.707107 0 -p -0.866025 -0.5 0 -p -0.965926 -0.258819 0 -p -0.765926 -0.258819 0 -p -0.965926 -0.258819 0 -p -1 0 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 -k 16 -k 17 -k 18 -k 19 -k 20 -k 21 -k 22 -k 23 -k 24 -k 25 -k 26 -k 27 -k 28 -k 29 -k 30 -k 31 -k 32 -k 33 -k 34 -k 35 -k 36 -k 37 -k 38 -k 39 -k 40 -k 41 -k 42 -k 43 -k 44 -k 45 -k 46 -k 47" planer = pm.PyNode(pm.mel.eval(planer_curve)) planer.rename("%s_planer" %prefix) arrow_curve = 'curve -d 1 -p 0 0 0 -p 0 0.377909 0 -p -0.0449662 0.378085 0 -p 0 0.460303 0 -p 0.0449662 0.378085 0 -p 0 0.377909 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 ;' arrow = pm.PyNode(pm.mel.eval(arrow_curve)) pm.makeIdentity(arrow, apply=True, t=True, r=True, s=True) arrow.rename("%s_arrow" %prefix) angle_curves = pm.circle(name="%s_angleCurve" %prefix, r=0.5) pm.aimConstraint(pos, angle_curves[0], mo=False, aimVector=[0,1,0], upVector=[-1,0,0], worldUpType='object', worldUpObject=loc) pm.parent(arrow, angle_curves) loc.angle >> angle_curves[-1].sweep posPointer = pm.curve(name='%s_posPointer'%prefix, d = 1, p = [(0,0,0), (0,0,1)]) pointer = pm.curve(name='%s_targetPointer'%prefix, d = 1, p = [(0,0,0), (0,0,0)]) pointer.inheritsTransform.set(0) cls1 = pm.cluster(pointer.cv[0], name='%s_pointerClusterStart' %prefix) cls2 = pm.cluster(pointer.cv[1], name='%s_pointerClusterEnd' %prefix) pm.parent(pos, planer, angle_curves[0], cls1, pointer, posPointer, display) pm.parent(display, loc, grp) pm.parent(cls2, loc, r=True) cls1[1].v.set(0) cls2[1].v.set(0) pos.v.set(0)
def follow_attribute(params): ''' This function will add the follow function to the Pole Vector Controls on the IK/FK Legs ''' # Declare the variables that will be used to create the follow attribute in the function root_ctl = params['ikRootControl'].name() goal_ctl = params['ikGoalControl'].name() pole_ctl = params['ikPoleControl'].name() pole_off = pole_ctl.replace('_ctl', '_off_exp') ik1_jnt = params['ikSkeleton'][0].name() #null_fp = cmds.createNode('transform', n='Auto_FollowBase' + '_' + root_ctl, p='rt_fk0_jnt') null_fp = cmds.createNode('transform', n='Auto_FollowBase' + '_' + root_ctl, p='noXform') null_ff = cmds.createNode('transform', n='Auto_FollowGoal' + '_' + goal_ctl, p=null_fp) # Parent the null groups under the noXform #cmds.parent(null_fp, 'noXform') # Create the Aim Constraints for the follow base pm.aimConstraint(goal_ctl, null_fp, weight=1, upVector=(1, 0, 0), worldUpObject=root_ctl, worldUpType="objectrotation", offset=(0, 0, 0), aimVector=(0, -1, 0), worldUpVector=(1, 0, 0)) cmds.pointConstraint(ik1_jnt, null_fp, mo=True) # Create the Aim Constraints for the follow goal pm.aimConstraint(goal_ctl, null_ff, weight=1, upVector=(0, 1, 0), worldUpObject=goal_ctl, worldUpType="objectrotation", offset=(0, 0, 0), aimVector=(0, -1, 0), worldUpVector=(1, 0, 0)) # Create the parent constraint for the pole vector control pole_vector_constraint = cmds.parentConstraint(null_ff, pole_off, mo=True) i = cmds.parentConstraint(pole_vector_constraint[0], wal=True, q=True) # Connect follow and pole vector control cmds.addAttr(goal_ctl, ln='poleVectorFollow', at='bool', k=True) cmds.connectAttr('{}.poleVectorFollow'.format(goal_ctl), '{}.{}'.format(str(pole_vector_constraint[0]), str(i[0])))
def create( self ): # # Create Kinect2 Joints # aimer = [] for kjot in self.k2map: tag = self.k2map[kjot][0] aimid = self.k2map[kjot][2] aim = None if aimid is None else self.k2map[aimid][0] aimv = (1,0,0) t = pm.xform( tag, q=True, ws=True, t=True ) pm.select( cl=True ) pm.joint( p=t, n=kjot ) if not aim is None: aimv = (-1,0,0) if pm.getAttr(aim+'.tx') < 0 else aimv aimer.append(pm.aimConstraint( aim, kjot, aim=aimv, wut='objectrotation', u=(0,1,0), wu=(0,1,0), wuo=tag )) pm.delete( aimer ) # # Make Joints Hierarchy # for kjot in self.k2map: parent = self.k2map[kjot][1] aimid = self.k2map[kjot][2] if not parent is None: pm.parent( kjot, self.k2map[kjot][1] ) if aimid is None: pm.setAttr( kjot+'.jointOrient', (0,0,0) ) # Freeze Transformations pm.makeIdentity( kjot, a=True, jo=False, t=False, r=True, s=False, n=0, pn=True ) # # Make Constraint # for kjot in self.k2map: tag = self.k2map[kjot][0] aimid = self.k2map[kjot][2] aim = None if aimid is None else self.k2map[aimid][0] aimv = (1,0,0) # Aim Constraint pm.pointConstraint( tag, kjot ) # Aim Constraint if not aim is None: aimv = (-1,0,0) if pm.getAttr(aim+'.tx') < 0 else aimv pm.aimConstraint( aim, kjot, aim=aimv, wut='objectrotation', u=(0,1,0), wu=(0,1,0), wuo=tag ) return
def setTpose(): selection = pm.ls(sl=1, type='joint') if selection: for jnt in selection: tempNull = pm.spaceLocator(name=jnt.name() + '_temp_loc') pm.delete(pm.pointConstraint(jnt, tempNull)) tempNull.translateX.set(100) pm.aimConstraint(tempNull, jnt, aimVector=[1, 0, 0], upVector=[0, 1, 0]) pm.delete(tempNull) mirrorJntRot(jnt)
def quickSpineCtrl(side, base): """ from control joint selection creates controls for spine, this function will build a quick spine control network """ ctrlJoints = pm.selected() conName = nameNode(base, side) print(ctrlJoints) ctrlBase = createControl(side, base + "Tip", "circleX", sdk=1, con=1) ctrlMid = createControl(side, base + "Mid", "circleX", sdk=1, con=1) ctrlEnd = createControl(side, base + "End", "circleX", sdk=1, con=1) print(ctrlBase, ctrlMid, ctrlEnd) locs = [] tangentLocs = [] for i in range(len(ctrlJoints)): if i == 0: tParent = pm.parentConstraint( ctrlJoints[i], ctrlBase[0], mo =False) tangentLocs.append(pm.spaceLocator(n = conName + "base_tangent")) locs.append(pm.spaceLocator(n= conName + "base_upVec")) elif i == 1: tParent = pm.parentConstraint( ctrlJoints[i], ctrlMid[0] , mo =False) locs.append(pm.spaceLocator(n= conName + "mid_upVec")) else: tParent = pm.parentConstraint( ctrlJoints[i], ctrlEnd[0] , mo =False) tangentLocs.append(pm.spaceLocator(n = conName + "end_tangent")) tanEndParent = pm.parentConstraint(ctrlEnd[0], ctrlMid[0], tangentLocs[1], mo = False) tanBaseParent = pm.parentConstraint(ctrlBase[0], ctrlMid[0], tangentLocs[0], mo = False) locs.append(pm.spaceLocator(n= conName + "end_upVec")) pm.delete(tanEndParent, tanBaseParent) pm.parent(tangentLocs[1], ctrlEnd[3] ) pm.parent(tangentLocs[0], ctrlBase[3] ) pm.delete(tParent) for i in range(len(ctrlJoints)): lParent = pm.parentConstraint(ctrlJoints[i], locs[i], mo=False) pm.delete(lParent) pm.parent(locs[i], ctrlJoints[i]) locs[i].translateY.set(15.0) if i == 0: pm.parent(ctrlJoints[i], ctrlBase[3]) elif i == 1: pm.parent(ctrlJoints[i], ctrlMid[3]) pm.parent(locs[i], w=True) else: pm.parent(ctrlJoints[i], ctrlEnd[3]) pm.pointConstraint(locs[0], locs[2], locs[1], mo=True) pm.pointConstraint(tangentLocs[0], tangentLocs[1], ctrlMid[1], mo=True) #aimConstraint -mo -weight 1 -aimVector 1 0 0 -upVector 0 1 0 -worldUpType "object" -worldUpObject testmid_upVec; pm.aimConstraint(tangentLocs[0], ctrlMid[1], weight=True, aimVector=(1,0,0), upVector=(0,1,0), worldUpType="object", worldUpObject=locs[1], mo=True)
def FKIK_query_orient(self, obj_list, *args): ''' Create aim constraint setup to query properly planar-aligned xyz euler orientations. @Argument(s): obj_list : List of 3 objects to determine planar relationship @Return: [[xyz], [xyz], [xyz]] ''' if not len(obj_list) == 3: raise RuntimeError('Must provide exactly 3 items in obj_list to query orientations correctly.') POS_list = self.query_translation(obj_list) # TODO: # Replace all this code with something a little # more elegant. # Likely something with OpenMaya for querying the # actual vectors and orientations of the objects # in world space? # Using cross products to determine the correct # planar relationships between guide positions. A_LOC = pm.spaceLocator() B_LOC = pm.spaceLocator() C_LOC = pm.spaceLocator() if self.debugging: print 'Created:', A_LOC, B_LOC, C_LOC A_LOC.setTranslation(POS_list[0]) B_LOC.setTranslation(POS_list[1]) C_LOC.setTranslation(POS_list[2]) A_orient = pm.aimConstraint(B_LOC, A_LOC, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=C_LOC) B_orient = pm.aimConstraint(C_LOC, B_LOC, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=A_LOC) C_orient = pm.aimConstraint(A_LOC, C_LOC, aimVector=[-1,0,0], upVector=[0,-1,0], worldUpType='object', worldUpObject=B_LOC) A_value = A_LOC.getRotation() B_value = B_LOC.getRotation() C_value = C_LOC.getRotation() if self.debugging: print ('Successfully completed the creation and query of guide orientation') print A_value, B_value, C_value # Add disposable items to the cleanup_queue self.cleanup_queue.extend([A_orient, B_orient, C_orient, A_LOC, B_LOC, C_LOC]) return [A_value, B_value, C_value]
def aimObject(toTarget, fromTarget): """ Aim object to the target. :param toTarget: `PyNode` or `list` object or world position to aim to :param fromTarget: `PyNode` object to transform :return: """ if isinstance(toTarget, list): targetObj = pm.createNode("transform") pm.xform(targetObj, t=toTarget, ws=1) pm.delete(pm.aimConstraint(targetObj, fromTarget, mo=0, wut=0)) pm.delete(targetObj) else: pm.delete(pm.aimConstraint(toTarget, fromTarget, mo=0, wut=0))
def addTwistCard(jnt): ''' Given a `BPJoint` to drive a twist, creates a card with sibling twist helper. ''' names = jnt.card.nameList(usePrefix=False) name = names[jnt.cardCon.index()] # Strip off the suffix if one exists if util.isMirrored(jnt): mirrorCode = jnt.card.rigData.get( 'mirrorCode', '') # &&& Can I always get the mirror code and always set it? suffix = config.jointSideSuffix(mirrorCode) name = name[:-len(suffix)] else: mirrorCode = '' name += 'Twist' card = makeCard(jointCount=1, jointNames=[name], rigInfo=None, size=(1, 1)) # &&& Can I prevent joints from being added to this card? # Keep the card scaled along the length of the bone. xform(card, piv=(0, .5, 0), ws=True) aimConstraint(jnt, card, aim=[0, -1, 0], u=[1, 0, 0], wut='objectrotation', wuo=jnt.cardCon.node(), wu=[0, 0, 1]) pointConstraint(jnt.parent, card) dist, grp = pdil.dagObj.measure(jnt, jnt.parent) grp.setParent(card) dist.setParent(card) dist.distance >> card.sy # The twist needs to stay on axis. card.start().tz.lock() card.extraNode[0] = jnt if mirrorCode: card.suffix.set(mirrorCode) with card.rigData as data: data[enums.RigData.rigCmd] = 'TwistHelper' card.sz.set(max(card.sy.get() / 4.0, 1.0)) card.start().setBPParent(jnt.parent) return card
def createTwistJnt(self, jnt=None, nfJnt=None, ikHandle=None): ''' Setup twist joint to use as angular diff object from no_roll jnt ''' twistJnt =pm.duplicate(jnt, n=jnt.name()+'_twistResult')[0] pm.delete(pm.listRelatives(twistJnt)) nfEnd = [x for x in pm.listRelatives(nfJnt, children=True) if x.type()=='joint'][0] pm.parent(twistJnt, nfJnt) pm.aimConstraint(nfEnd, twistJnt, aimVector=(1,0,0), worldUpVector=(0,1,0), wuo=jnt, wut='objectrotation') #--- Connect twist result to ikSpline twist pm.connectAttr('%s.rotateX'%twistJnt, '%s.twist'%ikHandle, f=True) return twistJnt
def bdRigEye(self): #create IK handles for the bind joints, for now getting the joints based on the name parts = [] if self.templateSide == 'both': parts = ['left','right'] else: parts = [self.templateSide] for side in parts: eyeLidsJnt = pm.ls(side + '*eyelid_*_01_jnt') eyeJoint = pm.ls(side + "*eye*jnt")[0] eyeCorners = pm.ls(side + "*eye*corner*01_jnt") eyeAnim = pm.ls(side + '_eye_anim') pm.select(cl=True) eyeAnimGrp = pm.group(n=side + '_eyelids_anim_GRP') pm.select(cl=True) pm.aimConstraint(eyeAnim[0],eyeJoint,offset = [0, 0, 0] ,weight=1 , aimVector =[0 ,0 ,1] ,upVector=[0, 1, 0] ,worldUpType="vector" ,worldUpVector= [0,1,0]) blinkUpJnt = pm.duplicate(eyeJoint,name = side + '_eyelid_upper_blink_jnt',po=True) blinkLowJnt = pm.duplicate(eyeJoint,name = side + '_eyelid_lower_blink_jnt',po=True) baseLidsJnt = pm.ls(side + '*lids*base') pm.parent([blinkUpJnt[0],blinkLowJnt[0]],baseLidsJnt[0]) for joint in (eyeLidsJnt + eyeCorners): endJoint = pm.listRelatives(joint,c=True,type='joint') ikName = endJoint[0].name().replace('02_bnd_jnt','ikHandle') ctrlName = endJoint[0].name().replace('02_bnd_jnt','anim') bdRigUtils.bdAddIk(joint.name(),endJoint[0].name(),'ikSCsolver',ikName) eyelidAnim,eyelidAnimGrp = bdRigUtils.bdBuildSquareController(endJoint[0].name(),ctrlName,0.2) pm.parent(eyelidAnimGrp , eyeAnimGrp) #bdRigUtils.bdBuildBoxController(endJoint[0].name(),ctrlName,0.2) if 'corner' not in ctrlName: bdRigUtils.bdAddAttributeMinMax(ctrlName,['BlinkPosition'],'double',-5,5,1) pm.parent(ikName,ctrlName) self.bdBuildJointStructure(joint,ctrlName,ikName) ''' allAnimsGrps = pm.ls(self.templateSide + '*eye*CON_??',type='transform') globalAnimGrp = pm.ls('controllers') pm.parent(allAnimsGrps,globalAnimGrp[0]) ''' self.bdAddEyeAttr(eyeAnim[0]) self.bdCreateVerticalFollow(side) self.bdCreateSideFollow(side) self.bdCreateBlink(side) self.bdCleanupGuides(side)
def orientXform(xform, aim_loc, aim_axis=(1, 0, 0), up_axis=(0, 1, 0), world_up=(0, 1, 0), freeze=False): xform = pm.ls(xform)[0] children = xform.listRelatives() if children: for child in children: child.setParent(None) target = pm.createNode('transform') target.setTranslation(aim_loc, ws=True) pm.delete( pm.aimConstraint(target, xform, aimVector=aim_axis, upVector=up_axis, worldUpVector=world_up)) pm.delete(target) if freeze: pm.makeIdentity(xform, apply=True) if children: for child in children: child.setParent(xform)
def createBendDeformerOnCurve(curveTransforms, upDir=(1,0,0), aimDir=(0,1,0)): '''Creates bend deformers on every curve and aims them at the end Args: curveTransforms ([pm.nt.Transform]): list of transforms with nurbsCurve shapes upDir (float, float, float): up direction for aim to orient the bend deformer Returns: ([pm.nt.nonLinear]): list of bend deformers Usage: createBendDeformerOnCurve(pm.ls(sl=True)) ''' bends=[] for curveTransform in curveTransforms: bendName = curveTransform.name().replace('CRV','BEND') bend = pm.nonLinear(curveTransform, type='bend', frontOfChain=True, curvature=0.0, lowBound=0, highBound=1) bend[0].rename(bendName.replace('BEND','BENDHDL')) bend[1].rename(bendName) startPosition = curveTransform.getShape().cv[0].getPosition(space='world') endPosition = curveTransform.getShape().cv[-1].getPosition(space='world') loc = pm.spaceLocator() pm.move(loc, endPosition, a=True) pm.move(bend[1], startPosition, a=True) aimConst = pm.aimConstraint( loc, bend[1], upVector=upDir, aimVector=aimDir ) pm.delete([loc, aimConst]) bends.append(bend) return bends
def orientJoint(joint, aim_loc, aim_axis=(1, 0, 0), up_axis=(0, 1, 0), world_up=(0, 1, 0)): joint = pm.ls(joint)[0] children = joint.listRelatives() if children: for child in children: child.setParent(None) target = pm.createNode('transform') target.setTranslation(aim_loc, ws=True) pm.delete( pm.aimConstraint(target, joint, aimVector=aim_axis, upVector=up_axis, worldUpVector=world_up)) pm.delete(target) if children: for child in children: child.setParent(joint) pm.makeIdentity(joint, apply=True)
def alignToVector(xform, aim_x=(1, 0, 0), aim_y=(0, 1, 0), freeze=False): """ Rotates transform so that axes align with specified world-space directions. Parameters ---------- xform : pm.nt.Transform Transform to rotate. aim_x : tuple, optional World-space direction for the x-axis of `xform`. aim_y : tuple, optional World-space direction for the y-axis of `xform`. If not orthogonal to `aim_x`, the y-axis will attempt to be as close as possible to this vector. freeze : bool, optional Freeze transformation if True. Default is False. """ xform = pm.ls(xform)[0] xf_node = pm.createNode('transform') pm.move(xf_node, xform.getTranslation(ws=True)) aim_node = pm.createNode('transform') pm.move(aim_node, xform.getTranslation(space='world') + aim_x) pm.delete(pm.aimConstraint(aim_node, xf_node, worldUpVector=aim_y), aim_node) xform.setRotation(xf_node.getRotation(ws=True), ws=True) pm.delete(xf_node) if freeze: pm.makeIdentity(xform, apply=True)
def makeAim(self): """Creates the aimConstraints joints for prevLoc to loc""" # each SPAN for i, jnt in enumerate(self.jnts): grp = self.grps[i] loc = self.locs[i] pmc.orientConstraint(loc, jnt, mo=False) if not i: # if root joint, pointConstrain(?) and move along - # next part is for each SPAN only continue prevJnt = self.jnts[i - 1] prevGrp = self.grps[i - 1] prevLoc = self.locs[i - 1] # if empty, getParent returns None, getChildren returns [] if jnt not in prevJnt.getChildren(): pmc.warning("It is recommended that joints be in a heirarchy," " and be selected in heirarchical order.") # get one locator to aim at the other, which produces rotation # values which can be piped into joint rotation axis = jnt.translate.get().normal() arc = jnt.jointOrient.get().normal() wuo = prevGrp #if not i: # wuo = self.ctrls[0] aim = pmc.aimConstraint(loc, prevLoc, aimVector=axis, upVector=arc, worldUpVector=arc, worldUpObject=wuo, wut="objectrotation")
def setNodeAxisVectors(node, oldA1="posY", oldA2="posX", newA1="posY", newA2="posX", orient=True): node = pm.PyNode(node) #these are world space vectors oldV1 = getNodeAxisVector(node, oldA1) oldV2 = getNodeAxisVector(node, oldA2) _logger.debug("%s vector: %s; %s vector: %s" % (oldA1, str(oldV1), oldA2, str(oldV2))) newV1 = g_vectorMap[newA1] newV2 = g_vectorMap[newA2] posL = pm.spaceLocator() aimL = pm.spaceLocator() upL = pm.spaceLocator() aimL.setParent(posL) upL.setParent(posL) pm.delete(pm.pointConstraint(node, posL, mo=False)) aimL.translate.set(oldV1) upL.translate.set(oldV2) pm.delete(pm.aimConstraint(aimL, node, aimVector=newV1, upVector=newV2, worldUpType='object', worldUpObject=upL)) pm.delete(posL) if orient: node.jox.set(node.jox.get() + node.rotateX.get()) node.joy.set(node.joy.get() + node.rotateY.get()) node.joz.set(node.joz.get() + node.rotateZ.get()) node.rotate.set([0, 0, 0])
def strokePath(node, radius=.1): """ Create a nurbs surface from a curve control """ curveNodes = separateShapes(node) for curveNode in curveNodes: shape = curveNode.listRelatives(type='nurbsCurve')[0] t = pm.pointOnCurve(shape, p=0, nt=1) pos = pm.pointOnCurve(shape, p=0) cir = pm.circle(r=radius)[0] pm.xform(cir, t=pos, ws=1) #align the circule along the curve l = pm.spaceLocator() pm.xform(l, t=[pos[0]+t[0], pos[1]+t[1], pos[2]+t[2]], ws=1) pm.delete(pm.aimConstraint(l, cir, aimVector=[0,0,1])) pm.delete(l) newxf = pm.extrude(cir, curveNode, rn=False, po=0, et=2, ucp=1, fpt=1, upn=1, scale=1, rsp=1, ch=1)[0] pm.delete(cir) pm.delete(curveNode.listRelatives(type='nurbsCurve')) parentShape(curveNode, newxf) if len(curveNodes) > 1: for i in range(1, len(curveNodes)): parentShape(curveNodes[0], curveNodes[i]) return curveNodes[0]
def orient_chain(self): """ aim parent to get right orientation of Locs """ pm.parent(*self, world=True) constraints = [] for node_a, node_b in zip(self[1:], self[:-1]): # ainConstrain with UP orientation after node_a list cnst = pm.aimConstraint(node_a, node_b, worldUpObject=node_a, worldUpType="objectrotation", worldUpVector=(0, 1, 0)) constraints.append(cnst) cnst = pm.orientConstraint(self[-2], self.list_of_joints[-1]) constraints.append(cnst) pm.delete(constraints) pm.makeIdentity(self, rotate=True, apply=True) transform.parenting(self)
def create(self): self.handle = pm.group(em=True) self.result = pm.group(em=True) self.aim = pm.group(em=True) self.up = pm.group(em=True) pm.parent(self.result, self.aim, self.up, self.handle ) # 초기위치 조정 mult = 20 self.aim.t.set(self.aimVec * mult) self.up.t.set(self.upVec * mult) self.aimConstraint = pm.aimConstraint(self.aim, self.result, aim=self.aimVec, u=self.upVec, wut='object', wuo=self.up) # 시각화 self.handle.displayHandle.set(True) #self.result.displayLocalAxis.set(True) # 어트리뷰트 잠금 setAttrs( self.result, 'tx','ty','tz','sx','sy','sz','v' ) setAttrs( self.aim, 'rx','ry','rz','sx','sy','sz','v' ) setAttrs( self.up, 'rx','ry','rz','sx','sy','sz','v' ) # 이름변경 self.setPrefix( self.prefix )
def poleVector(self, name='', mid='', posMultiplier=1): if name == '': name = self.name poleVector = rig_transform(0, name=name + 'PoleVector', type='locator').object pm.delete(pm.parentConstraint(self.start, self.end, poleVector)) pm.delete(pm.aimConstraint(mid, poleVector, mo=False)) startPos = pm.xform(self.start, translation=True, query=True, ws=True) midPos = pm.xform(self.end, translation=True, query=True, ws=True) poleVectorPos = pm.xform(poleVector, translation=True, query=True, ws=True) pvDistance = lengthVector(midPos, poleVectorPos) pm.xform(poleVector, translation=[pvDistance * posMultiplier, 0, 0], os=True, r=True) pm.poleVectorConstraint(poleVector, self.handle) # create pv return poleVector
def build(crv, name=''): ''' creates a Marco Giordano style eyelid rig ''' params = [curve.getClosestPointOnCurve(crv=crv, point = pmc.pointPosition(cv)) for cv in crv.cv[:]] mainGrp = pmc.group(empty=1, name='%s_grp' % name) baseGrp = pmc.group(empty=1, name='%s_base_grp' % name) baseGrp.setParent(mainGrp) mps = curve.nodesAlongCurve(crv=crv.name(), numNodes=len(params), name=name) for index in range(len(params)): mp = common.getPyNode(mps['mpNodes'][index]) mp.uValue.set(params[index]) mp.fractionMode.set(0) grp = common.getPyNode(mps['grps'][index]) aimGrp = pmc.group(empty=1, name='%s_%s_aim_grp' % (name, str(index))) aimGrp.setParent(baseGrp) con = pmc.aimConstraint(grp, aimGrp, mo=0, wut=2, wuo=baseGrp.name()) pmc.select(aimGrp, r=1) j = pmc.joint(name='%s_%s_jnt' % (name, str(index))) j.tx.set(10)
def bdCreateDrvJnt(self,crv1,crv2): pm.select(cl=1) drv1 = self.startJnt.duplicate(po=1)[0] pm.parent(drv1,w=1) drv1.rename(self.nameRbn + '_DRV_1_JNT') radius = self.startJnt.radius.get() drv1.radius.set(radius*1.5) pm.parentConstraint(self.startJnt,drv1,mo=0) drv2 = drv1.duplicate(po=1)[0] drv2.rename(self.nameRbn + '_DRV_2_JNT') drv3 = drv1.duplicate(po=1)[0] drv3.rename(self.nameRbn + '_DRV_3_JNT') pm.parentConstraint(self.endJnt,drv3,mo=0) startPos,endPos = self.bdGetPos(0) drv1.setTranslation(startPos) drv3.setTranslation(endPos) drv2CtrlGrp = self.bdCreateJntCtrl(drv2,0.20) pm.pointConstraint(drv1,drv2CtrlGrp,mo=0 ) pm.pointConstraint(drv3,drv2CtrlGrp,mo=0 ) aimLocator = pm.spaceLocator(n=drv2CtrlGrp.name().replace('DRV_2_CTRL_GRP','AIM')) drv2CtrlGrpPos = drv2CtrlGrp.getTranslation(space='world') aimLocator.setPosition(drv2CtrlGrpPos) for axis in ['X','Y','Z']: aimLocator.attr('localScale'+axis).set(0.1) aimLocatorGrp = pm.group(aimLocator,n=aimLocator.name() + '_grp') aimLocatorGrp.centerPivots() if self.direction == 'hor': pm.move(0,0.5,0, aimLocatorGrp, r=1, os=1, wd=1) elif self.direction == 'vert': pm.move(0,0,0.5, aimLocatorGrp, r=1, os=1, wd=1) pm.parentConstraint(self.startJnt,aimLocatorGrp,mo=1) print aimLocator.getTranslation(space='world').x if aimLocator.getTranslation(space='world').x > 0: pm.aimConstraint(drv3,drv2CtrlGrp,mo=1,weight=1,aimVector=[1, 0, 0],upVector = [0, 1, 0],worldUpType="object" , worldUpObject = aimLocator) else: pm.aimConstraint(drv3,drv2CtrlGrp,mo=1,weight=1,aimVector=[-1, 0, 0],upVector = [0, 1, 0],worldUpType="object" , worldUpObject = aimLocator) drvGrp = pm.group([drv1,drv2CtrlGrp,drv3],n=self.nameRbn + '_DRV_GRP') crv1Skin = pm.skinCluster(drv1,drv2,drv3,crv1) crv1Skin = pm.skinCluster(drv1,drv2,drv3,crv2) pm.parent(aimLocatorGrp,drvGrp) return drvGrp
def addEyelashCollider(bnd, browCrv): ''' browCrv = pm.PyNode(u'LT_eyeBrowCollide_crv') bnd = pm.PyNode('FACE:LT_eye_aimAt_bnd_16') ''' childGrp = bnd.getChildren()[0] # create vertCrv vertCrv = pm.curve(p=((0,-10,0),(0,10,0)), n=bnd+'_vertCrv', d=1) # constrain to bnd pm.pointConstraint(bnd, vertCrv) # intersect crvInt = pm.createNode('curveIntersect', n=bnd+'_collider_int') browCrv.worldSpace >> crvInt.inputCurve1 vertCrv.worldSpace >> crvInt.inputCurve2 crvInt.useDirection.set(True) # calculate direction of bnd's x-axis mat = bnd.getMatrix(ws=True) dir = pm.dt.Vector(1,0,0) * mat crvInt.direction.set(dir) # get point on crv poci = pm.createNode('pointOnCurveInfo', n=bnd+'_collider_poci') browCrv.worldSpace >> poci.inputCurve crvInt.parameter1[0] >> poci.parameter # aim loc aimLoc = pm.spaceLocator(n=bnd+'_collide_aimLoc') aimLoc.localScale.set(0.1,0.1,0.1) poci.position >> aimLoc.t # limit null limitNull = pm.group(em=True, n=bnd+'_collider_limit') bnd | limitNull limitNull.setMatrix(pm.dt.Matrix()) # aim to aimLoc pm.aimConstraint(aimLoc, limitNull, aim=(1,0,0), wuo=bnd, wu=(0,1,0), u=(0,1,0), wut='objectrotation') # limit childGrp while keeping bnd's orientation limitNull | childGrp pm.orientConstraint(bnd, childGrp) childGrp.minRotZLimit.set(10) childGrp.minRotZLimitEnable.set(True) # cleanup grp = pm.group(vertCrv, aimLoc, n=bnd+'_collide_grp') grp.addAttr('minRotate', k=True, dv=10) grp.minRotate >> childGrp.minRotZLimit return grp
def aimAt(master, slave, upRotObject, orientation, flipUp=False): aimVec = orientation.getAxis('aim') upVec = orientation.getAxis('up') worldUpVec = upVec if flipUp: worldUpVec = [x*-1 for x in worldUpVec] cst = pm.aimConstraint(master, slave, aim=aimVec, u=upVec, wu=worldUpVec, mo=False, wut='objectRotation') pm.delete(cst)
def createManipulatorAndIkHandleConstraints(self): pm.select(cl = True) #manip_aim indicator aim grp pm.aimConstraint(self.manip_leg_complete, self.manip_aim_indicator_aim_grp, aim = (1,0,0), u = (0,1,0), wut = 'objectrotation' , wu = (0,1,0) ,mo = True) pm.select(cl = True) #manip_leg_ik pm.parentConstraint(self.manip_aim_indicator, self.manip_leg_ik_grp, mo = True) pm.scaleConstraint(self.manip_aim_indicator, self.manip_leg_ik_grp, mo = True) pm.pointConstraint(self.manip_leg_complete, self.manip_leg_ik_point_grp, mo = True) pm.select(cl = True) #poleVector pm.parentConstraint(self.manip_aim_indicator, self.leg_ik_pole_vector_locator_grp, mo = True) pm.scaleConstraint(self.manip_aim_indicator, self.leg_ik_pole_vector_locator_grp, mo = True) pm.select(cl = True) #poleVectorConstraint pm.poleVectorConstraint(self.leg_ik_pole_vector_locator, self.leg_ik_handle) pm.select(cl = True) #IkHandle pm.parentConstraint(self.manip_leg_ik, self.leg_ik_handle_grp, mo = True) pm.scaleConstraint(self.manip_leg_ik, self.leg_ik_handle_grp, mo = True) pm.select(cl = True) #ik_j_tip pm.orientConstraint(self.manip_leg_ik, self.leg_ik_j_tip, mo = True) pm.select(cl = True) #ik_j_grp pm.parentConstraint(self.manip_leg_base, self.leg_ik_j_grp, mo = True) pm.scaleConstraint(self.manip_leg_base, self.leg_ik_j_grp, mo = True) pm.select(cl = True)
def constrainJoints(self, a=None, b=None, jnts=None): # Select two end joints, creates mid joint. # Constrains mid joint to follow and aim at second end joint. # Setup up locator loc = pm.spaceLocator(name='%s_upLoc' % a) pm.delete(pm.pointConstraint(b, loc, mo=0)) # Adjust placement of Up object here moveAxis = pm.optionMenu(self.axisFld, q=1, value=1) if moveAxis == 'X': pm.move(20, loc, moveX=1) if moveAxis == 'Y': pm.move(20, loc, moveY=1) if moveAxis == 'Z': pm.move(20, loc, moveZ=1) pm.parent(loc, a) # Constrain joint for j in jnts: pm.pointConstraint(a, b, j, mo=1) pm.aimConstraint(b, j, wut='object', wuo=loc.name(), mo=1)
def rig_piston(head, rod, weight, crankshaft, rotatePattern, parent=False): rod_grp = pm.group(em=True,n=rod.replace('LOC','GRP')) head_grp = pm.group(em=True,n=head.replace('LOC','GRP')) head_pos = pm.spaceLocator(n=head.replace('LOC','pos_LOC')) pos.matchPos(head, [head_pos]) pos.matchPos(rod, [rod_grp], type=1, ws=True, silent=True) rod.setParent(rod_grp) pos.matchPos(head, [head_grp]) head.setParent(head_grp) pm.parentConstraint(weight, rod_grp, skipRotate=('x','y','z'),mo=True) pm.aimConstraint(head, rod, aimVector=(0,1,0), upVector=(0,1,0), worldUpType='vector',worldUpVector=(0,1,0), offset=(0,0,0),weight=1,skip=('y','z'), mo=True) dist=pm.shadingNode('distanceBetween',asUtility=True) head_pos.translate.connect(dist.point1) rod_grp.translate.connect(dist.point2) pma = pm.shadingNode('plusMinusAverage',asUtility=True) pma.input2D[1].input2Dx.set( dist.distance.get()) dist.distance.connect( pma.input2D[0].input2Dx) pma.operation.set(2) md = pm.shadingNode("multiplyDivide", asUtility=True) pma.output2D.output2Dx.connect(md.input1.input1X) md.input2.input2X.set(-1) md.outputX.connect(head.ty) head_pos.visibility.set(0) if parent: rod_grp.setParent(parent) head_grp.setParent(parent) head_pos.setParent(parent) if rotatePattern: #Same direction if the input is 0 crankshaft.rotateX.connect(weight.rotateX) else: #Reverse if the input is 0 md = pm.shadingNode('multiplyDivide',asUtility=True) crankshaft.rotateX.connect(md.input1X) md.outputX.connect(weight.rotateX) md.input2X.set(-1)
def build(self, extract_world_up, name=None, *args, **kwargs): super(NonRollJoint, self).build(name=name, *args, **kwargs) pymel.select(clear=True) self.start = pymel.joint() self.end = pymel.joint() self.end.setTranslation([1,0,0]) pymel.makeIdentity((self.start, self.end), apply=True, r=True) self.ikHandle, ikEffector = pymel.ikHandle( solver='ikRPsolver', startJoint=self.start, endEffector=self.end) self.ikHandle.poleVectorX.set(0) self.ikHandle.poleVectorY.set(0) self.ikHandle.poleVectorZ.set(0) # Name stuff, if no nomenclature, cry, node will be named by the base class start_name = name + "_jntStart" end_name = name + "_jntEnd" ik_handle_name = name + "_ikHandle" ik_effector_name = name + "_ikEffector" twist_extract_name = name + "_twistExtractor" self.start.rename(start_name) self.end.rename(end_name) self.ikHandle.rename(ik_handle_name) ikEffector.rename(ik_effector_name) # Create the extract node for the twist information self.twist_extractor = pymel.createNode('transform') self.twist_extractor.rename(twist_extract_name) self.twist_extractor.setMatrix(self.start.getMatrix(worldSpace=True), worldSpace=True) self.twist_extractor.setParent(self.start) pymel.aimConstraint(self.end, self.twist_extractor, worldUpType=2, worldUpObject=extract_world_up) # Set Hierarchy self.start.setParent(self.node) self.ikHandle.setParent(self.node)
def centeredCtl(startJoint, endJoint, ctl, centerDown='posY'): """ Setup a control to be 'centered' down a bone. @param startJoint: the joint the control should start at @param endJoint: the joint the control should end at @param ctl: the control node @param centerDown: the control axis to stretch to center the node """ o = utils.Orientation() o.setAxis('aim', centerDown) pm.pointConstraint(startJoint, endJoint, ctl) pm.aimConstraint(endJoint, ctl, aim=o.getAxis('aim'), upVector=o.getAxis('up'), wu=o.getAxis('up'), worldUpType='objectRotation', worldUpObject=startJoint) #set up network to measure the distance mdn = MC.createNode('multiplyDivide', n='%s_centeredctl_mdn' % ctl) MC.select(cl=1) dd = MC.createNode('distanceBetween', n='%s_center_dd' % ctl) MC.connectAttr('%s.worldMatrix' % startJoint, "%s.im1" % dd) MC.connectAttr('%s.worldMatrix' % endJoint, "%s.im2" % dd) MC.connectAttr('%s.distance' % dd, '%s.input1X' % mdn) #find the amount we need to scale by. Ctls are generally built to a scale of 1 #unit by default. scale = getInfo(ctl)['s'] scale = scale[utils.indexFromVector(o.getAxis('aim'))] scale = (1.0/(scale*2)) MC.setAttr("%s.input2X" % mdn, scale) scaleAttr = 'scale%s' % o.getAxis('aim', asString=True)[3] MC.connectAttr("%s.outputX" % mdn, "%s.%s" % (ctl, scaleAttr))