def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ applyop.aimCns(self.ref_base, self.tip_ctl, axis="yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.ctl, maintainOffset=False) applyop.aimCns(self.ref_tip, self.ctl, axis="-yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.tip_ctl, maintainOffset=False) bIncrement = 1.0 / (self.settings["div"] - 1) blend = 0 for i, div_cns in enumerate(self.div_cns): intMatrix = applyop.gear_intmatrix_op( self.ref_base.attr("worldMatrix"), self.ref_tip.attr("worldMatrix"), blend) applyop.gear_mulmatrix_op(intMatrix.attr("output"), div_cns.attr("parentInverseMatrix[0]"), div_cns) blend = blend + bIncrement
def addOperators(self): aim_base = aop.aimCns(self.ref_base, self.tip_ctl, axis="yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.ctl, maintainOffset=False) aim_tip = aop.aimCns(self.ref_tip, self.ctl, axis="-yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.tip_ctl, maintainOffset=False) bIncrement = 1.0 / (self.settings["div"] - 1) blend = 0 for i, div_cns in enumerate(self.div_cns): intMatrix = aop.gear_intmatrix_op( self.ref_base.attr("worldMatrix"), self.ref_tip.attr("worldMatrix"), blend) aop.gear_mulmatrix_op(intMatrix.attr("output"), div_cns.attr("parentInverseMatrix[0]"), div_cns) blend = blend + bIncrement
def createInterpolateTransform(objects=None, blend=.5, *args): """ Create space locator and apply gear_intmatrix_op, to interpolate the his pose between 2 selected objects. Args: objects (None or list of 2 dagNode, optional): The 2 dagNode to interpolate the transform. blend (float, optional): The interpolation blend factor. *args: Maya's dummy Returns: pyNode: The new transformation witht the interpolate matrix node applied. """ if objects or len(pm.selected()) >= 2: if objects: refA = objects[0] refB = objects[1] else : refA = pm.selected()[0] refB = pm.selected()[1] intMatrix = aop.gear_intmatrix_op(refA.attr("worldMatrix"), refB.attr("worldMatrix"), blend) intTrans = pri.addTransform(refA, refA.name()+"_INTER_"+refB.name(), dt.Matrix()) aop.gear_mulmatrix_op(intMatrix.attr("output"), intTrans.attr("parentInverseMatrix[0]"), intTrans) pm.displayInfo("Interpolated Transform: " + intTrans.name() + " created") else: pm.displayWarning("Please select 2 objects. ") return return intTrans
def addOperators(self): """Create operators and set the relations for the component rig Apply operators/Solvers, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ applyop.aimCns(self.ref_base, self.squash_ctl, axis="yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.ctl, maintainOffset=False) applyop.aimCns(self.ref_squash, self.ctl, axis="-yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.squash_ctl, maintainOffset=False) bIncrement = 1.0 blend = 0 for i, div_cns in enumerate(self.div_cns): intMatrix = applyop.gear_intmatrix_op( self.ref_base.attr("worldMatrix"), self.ref_squash.attr("worldMatrix"), blend) applyop.gear_mulmatrix_op(intMatrix.attr("output"), div_cns.attr("parentInverseMatrix[0]"), div_cns) blend = blend + bIncrement d = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) dist_node = node.createDistNode(self.squash_ctl, self.ctl) rootWorld_node = node.createDecomposeMatrixNode( self.ctl.attr("worldMatrix")) div_node = node.createDivNode(dist_node + ".distance", rootWorld_node + ".outputScaleY") div_node = node.createDivNode(div_node + ".outputX", d) rev_node = node.createReverseNode(div_node + ".outputX") add_node = pm.createNode("plusMinusAverage") add_node.input1D[0].set(1.0) rev_node.outputX >> add_node.input1D[1] div_node.outputX >> self.ref_base.scaleY add_node.output1D >> self.ref_base.scaleX add_node.output1D >> self.ref_base.scaleZ
def addOperators(self): aop.aimCns(self.ref_base, self.squash_ctl, axis="yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.ctl, maintainOffset=False) aop.aimCns(self.ref_squash, self.ctl, axis="-yx", wupType=2, wupVector=[1, 0, 0], wupObject=self.squash_ctl, maintainOffset=False) bIncrement = 1.0 blend = 0 for i, div_cns in enumerate(self.div_cns): intMatrix = aop.gear_intmatrix_op( self.ref_base.attr("worldMatrix"), self.ref_squash.attr("worldMatrix"), blend) aop.gear_mulmatrix_op(intMatrix.attr("output"), div_cns.attr("parentInverseMatrix[0]"), div_cns) blend = blend + bIncrement d = vec.getDistance(self.guide.apos[0], self.guide.apos[1]) dist_node = nod.createDistNode(self.squash_ctl, self.ctl) rootWorld_node = nod.createDecomposeMatrixNode( self.ctl.attr("worldMatrix")) div_node = nod.createDivNode(dist_node + ".distance", rootWorld_node + ".outputScaleY") div_node = nod.createDivNode(div_node + ".outputX", d) rev_node = nod.createReverseNode(div_node + ".outputX") add_node = pm.createNode("plusMinusAverage") add_node.input1D[0].set(1.0) rev_node.outputX >> add_node.input1D[1] div_node.outputX >> self.ref_base.scaleY add_node.output1D >> self.ref_base.scaleX add_node.output1D >> self.ref_base.scaleZ
def createInterpolateTransform(*args): """ Create space locator and apply gear_intmatrix_op, to interpolate the his pose between 2 selected objects. """ if len(pm.selected()) == 2: refA = pm.selected()[0] refB = pm.selected()[1] intMatrix = aop.gear_intmatrix_op(refA.attr("worldMatrix"), refB.attr("worldMatrix"), .5) intTrans = pri.addTransform(refA, refA.name() + "_INTER_" + refB.name(), dt.Matrix()) aop.gear_mulmatrix_op(intMatrix.attr("output"), intTrans.attr("parentInverseMatrix[0]"), intTrans) pm.displayInfo("Interpolated Transform: " + intTrans.name() + "created") else: pm.displayWarning("Please select 2 objects. ")
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # Tangent position --------------------------------- # common part d = vector.getDistance(self.guide.pos["root"], self.guide.pos["neck"]) dist_node = node.createDistNode(self.root, self.ik_ctl) rootWorld_node = node.createDecomposeMatrixNode( self.root.attr("worldMatrix")) div_node = node.createDivNode(dist_node + ".distance", rootWorld_node + ".outputScaleX") div_node = node.createDivNode(div_node + ".outputX", d) # tan0 mul_node = node.createMulNode(self.tan0_att, self.tan0_loc.getAttr("ty")) res_node = node.createMulNode(mul_node + ".outputX", div_node + ".outputX") pm.connectAttr(res_node + ".outputX", self.tan0_loc + ".ty") # tan1 mul_node = node.createMulNode(self.tan1_att, self.tan1_loc.getAttr("ty")) res_node = node.createMulNode(mul_node + ".outputX", div_node + ".outputX") pm.connectAttr(res_node + ".outputX", self.tan1_loc.attr("ty")) # Curves ------------------------------------------- op = applyop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5, .5, .5) pm.connectAttr(self.maxstretch_att, op + ".maxstretch") pm.connectAttr(self.maxsquash_att, op + ".maxsquash") pm.connectAttr(self.softness_att, op + ".softness") # Volume driver ------------------------------------ crv_node = node.createCurveInfoNode(self.slv_crv) # Division ----------------------------------------- for i in range(self.settings["division"]): # References u = i / (self.settings["division"] - 1.0) cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u, True) cns.setAttr("frontAxis", 1) # front axis is 'Y' cns.setAttr("upAxis", 2) # front axis is 'Z' # Roll intMatrix = applyop.gear_intmatrix_op( self.intMRef + ".worldMatrix", self.ik_ctl + ".worldMatrix", u) dm_node = node.createDecomposeMatrixNode(intMatrix + ".output") pm.connectAttr(dm_node + ".outputRotate", self.twister[i].attr("rotate")) pm.parentConstraint(self.twister[i], self.ref_twist[i], maintainOffset=True) pm.connectAttr(self.ref_twist[i] + ".translate", cns + ".worldUpVector") # Squash n Stretch op = applyop.gear_squashstretch2_op(self.fk_npo[i], self.root, pm.arclen(self.slv_crv), "y") pm.connectAttr(self.volume_att, op + ".blend") pm.connectAttr(crv_node + ".arcLength", op + ".driver") pm.connectAttr(self.st_att[i], op + ".stretch") pm.connectAttr(self.sq_att[i], op + ".squash") op.setAttr("driver_min", .1) # scl compas if i != 0: div_node = node.createDivNode([1, 1, 1], [ self.fk_npo[i - 1] + ".sx", self.fk_npo[i - 1] + ".sy", self.fk_npo[i - 1] + ".sz" ]) pm.connectAttr(div_node + ".output", self.scl_npo[i] + ".scale") # Controlers if i == 0: mulmat_node = applyop.gear_mulmatrix_op( self.div_cns[i].attr("worldMatrix"), self.root.attr("worldInverseMatrix")) else: mulmat_node = applyop.gear_mulmatrix_op( self.div_cns[i].attr("worldMatrix"), self.div_cns[i - 1].attr("worldInverseMatrix")) dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output") pm.connectAttr(dm_node + ".outputTranslate", self.fk_npo[i].attr("t")) pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r")) # Orientation Lock if i == self.settings["division"] - 1: dm_node = node.createDecomposeMatrixNode(self.ik_ctl + ".worldMatrix") blend_node = node.createBlendNode( [dm_node + ".outputRotate%s" % s for s in "XYZ"], [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori_att) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node + ".output", self.div_cns[i] + ".rotate") # Head --------------------------------------------- self.fk_ctl[-1].addChild(self.head_cns) # scale compensation dm_node = node.createDecomposeMatrixNode(self.scl_npo[0] + ".parentInverseMatrix") pm.connectAttr(dm_node + ".outputScale", self.scl_npo[0] + ".scale")
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # 1 bone chain Upv ref ============================================== self.ikHandleUpvRef = primitive.addIkHandle( self.root, self.getName("ikHandleArmChainUpvRef"), self.armChainUpvRef, "ikSCsolver") pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef) pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True) # Visibilities ------------------------------------- # fk fkvis_node = node.createReverseNode(self.blend_att) for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) if self.settings["ikTR"]: for shp in self.ikRot_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- attribute.setRotOrder(self.fk0_ctl, "XZY") attribute.setRotOrder(self.fk1_ctl, "XYZ") attribute.setRotOrder(self.fk2_ctl, "YZX") attribute.setRotOrder(self.ik_ctl, "XYZ") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc] o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk_ctl[0], self.fk_ctl[1], self.fk_ref, self.length0, self.length1, self.negate) if self.settings["ikTR"]: # connect the control inputs outEff_dm = o_node.listConnections(c=True)[-1][1] inAttr = self.ikRot_npo.attr("translate") outEff_dm.attr("outputTranslate") >> inAttr outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale") dm_node = node.createDecomposeMatrixNode(o_node.attr("outB")) dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate") # rotation mulM_node = applyop.gear_mulmatrix_op( self.ikRot_ctl.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) intM_node = applyop.gear_intmatrix_op(o_node.attr("outEff"), mulM_node.attr("output"), o_node.attr("blend")) dm_node = node.createDecomposeMatrixNode(intM_node.attr("output")) dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate") transform.matchWorldTransform(self.fk2_ctl, self.ikRot_cns) # scale: this fix the scalin popping issue intM_node = applyop.gear_intmatrix_op( self.fk2_ctl.attr("worldMatrix"), self.ik_ctl_ref.attr("worldMatrix"), o_node.attr("blend")) mulM_node = applyop.gear_mulmatrix_op( intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix")) dm_node = node.createDecomposeMatrixNode(mulM_node.attr("output")) dm_node.attr("outputScale") >> self.eff_loc.attr("scale") pm.connectAttr(self.blend_att, o_node + ".blend") if self.negate: mulVal = -1 else: mulVal = 1 node.createMulNode(self.roll_att, mulVal, o_node + ".roll") pm.connectAttr(self.scale_att, o_node + ".scaleA") pm.connectAttr(self.scale_att, o_node + ".scaleB") pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch") pm.connectAttr(self.slide_att, o_node + ".slide") pm.connectAttr(self.softness_att, o_node + ".softness") pm.connectAttr(self.reverse_att, o_node + ".reverse") # Twist references --------------------------------- pm.pointConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX) pm.orientConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) o_node = applyop.gear_mulmatrix_op(self.eff_loc.attr( "worldMatrix"), self.root.attr("worldInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.tws2_npo.attr("translate")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate")) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.tws2_rot.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") attribute.setRotOrder(self.tws2_rot, "XYZ") pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate") self.tws0_rot.setAttr("sx", .001) self.tws2_rot.setAttr("sx", .001) add_node = node.createAddNode(self.roundness_att, .001) pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx")) pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX") # Roll Shoulder applyop.splineIK(self.getName("rollRef"), self.rollRef, parent=self.root, cParent=self.bone0) # Volume ------------------------------------------- distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc) distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc) add_node = node.createAddNode(distA_node + ".distance", distB_node + ".distance") div_node = node.createDivNode(add_node + ".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix") div_node2 = node.createDivNode(div_node + ".outputX", dm_node + ".outputScaleX") self.volDriver_att = div_node2 + ".outputX" if self.settings["extraTweak"]: for tweak_ctl in self.tweak_ctl: for shp in tweak_ctl.getShapes(): pm.connectAttr(self.tweakVis_att, shp.attr("visibility")) # Divisions ---------------------------------------- # at 0 or 1 the division will follow exactly the rotation of the # controler.. and we wont have this nice tangent + roll for i, div_cns in enumerate(self.div_cns): if i < (self.settings["div0"] + 1): perc = i * .5 / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = .49 elif i < (self.settings["div0"] + 3): perc = .50 elif i < (self.settings["div0"] + 4): perc = .51 else: perc = .5 + \ (i - self.settings["div0"] - 3.0) * .5 / \ (self.settings["div1"] + 1.0) perc = max(.001, min(.990, perc)) # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1 - perc, 40) else: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc, 40) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") # Squash n Stretch o_node = applyop.gear_squashstretch2_op( div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, o_node + ".blend") pm.connectAttr(self.volDriver_att, o_node + ".driver") pm.connectAttr(self.st_att[i], o_node + ".stretch") pm.connectAttr(self.sq_att[i], o_node + ".squash") # match IK/FK ref pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True) pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True) if self.settings["ikTR"]: transform.matchWorldTransform(self.ikRot_ctl, self.match_ikRot) transform.matchWorldTransform(self.fk_ctl[2], self.match_fk2) return
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # Auto bend ---------------------------- if self.settings["autoBend"]: mul_node = node.createMulNode( [self.autoBendChain[0].ry, self.autoBendChain[0].rz], [self.sideBend_att, self.frontBend_att]) mul_node.outputX >> self.ik1autoRot_lvl.rz mul_node.outputY >> self.ik1autoRot_lvl.rx self.ikHandleAutoBend = primitive.addIkHandle( self.autoBend_ctl, self.getName("ikHandleAutoBend"), self.autoBendChain, "ikSCsolver") # Tangent position --------------------------------- # common part d = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) dist_node = node.createDistNode(self.ik0_ctl, self.ik1_ctl) rootWorld_node = node.createDecomposeMatrixNode( self.root.attr("worldMatrix")) div_node = node.createDivNode(dist_node + ".distance", rootWorld_node + ".outputScaleX") div_node = node.createDivNode(div_node + ".outputX", d) # tan0 mul_node = node.createMulNode(self.tan0_att, self.tan0_npo.getAttr("ty")) res_node = node.createMulNode(mul_node + ".outputX", div_node + ".outputX") pm.connectAttr(res_node + ".outputX", self.tan0_npo.attr("ty")) # tan1 mul_node = node.createMulNode(self.tan1_att, self.tan1_npo.getAttr("ty")) res_node = node.createMulNode(mul_node + ".outputX", div_node + ".outputX") pm.connectAttr(res_node + ".outputX", self.tan1_npo.attr("ty")) # Tangent Mid -------------------------------------- if self.settings["centralTangent"]: tanIntMat = applyop.gear_intmatrix_op( self.tan0_npo.attr("worldMatrix"), self.tan1_npo.attr("worldMatrix"), .5) applyop.gear_mulmatrix_op( tanIntMat.attr("output"), self.tan_npo.attr("parentInverseMatrix[0]"), self.tan_npo) pm.connectAttr(self.tan_ctl.attr("translate"), self.tan0_off.attr("translate")) pm.connectAttr(self.tan_ctl.attr("translate"), self.tan1_off.attr("translate")) # Curves ------------------------------------------- op = applyop.gear_curveslide2_op( self.slv_crv, self.mst_crv, 0, 1.5, .5, .5) pm.connectAttr(self.position_att, op + ".position") pm.connectAttr(self.maxstretch_att, op + ".maxstretch") pm.connectAttr(self.maxsquash_att, op + ".maxsquash") pm.connectAttr(self.softness_att, op + ".softness") # Volume driver ------------------------------------ crv_node = node.createCurveInfoNode(self.slv_crv) # Division ----------------------------------------- for i in range(self.settings["division"]): # References u = i / (self.settings["division"] - 1.0) cns = applyop.pathCns( self.div_cns[i], self.slv_crv, False, u, True) cns.setAttr("frontAxis", 1) # front axis is 'Y' cns.setAttr("upAxis", 0) # front axis is 'X' # Roll intMatrix = applyop.gear_intmatrix_op( self.ik0_ctl + ".worldMatrix", self.ik1_ctl + ".worldMatrix", u) dm_node = node.createDecomposeMatrixNode(intMatrix + ".output") pm.connectAttr(dm_node + ".outputRotate", self.twister[i].attr("rotate")) pm.parentConstraint(self.twister[i], self.ref_twist[i], maintainOffset=True) pm.connectAttr(self.ref_twist[i] + ".translate", cns + ".worldUpVector") # compensate scale reference div_node = node.createDivNode([1, 1, 1], [rootWorld_node + ".outputScaleX", rootWorld_node + ".outputScaleY", rootWorld_node + ".outputScaleZ"]) # Squash n Stretch op = applyop.gear_squashstretch2_op( self.scl_transforms[i], self.root, pm.arclen(self.slv_crv), "y", div_node + ".output") pm.connectAttr(self.volume_att, op + ".blend") pm.connectAttr(crv_node + ".arcLength", op + ".driver") pm.connectAttr(self.st_att[i], op + ".stretch") pm.connectAttr(self.sq_att[i], op + ".squash") # Controlers if i == 0: mulmat_node = applyop.gear_mulmatrix_op( self.div_cns[i].attr("worldMatrix"), self.root.attr("worldInverseMatrix")) dm_node = node.createDecomposeMatrixNode( mulmat_node + ".output") pm.connectAttr(dm_node + ".outputTranslate", self.fk_npo[i].attr("t")) else: mulmat_node = applyop.gear_mulmatrix_op( self.div_cns[i].attr("worldMatrix"), self.div_cns[i - 1].attr("worldInverseMatrix")) dm_node = node.createDecomposeMatrixNode( mulmat_node + ".output") mul_node = node.createMulNode(div_node + ".output", dm_node + ".outputTranslate") pm.connectAttr(mul_node + ".output", self.fk_npo[i].attr("t")) pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r")) # Orientation Lock if i == 0: dm_node = node.createDecomposeMatrixNode( self.ik0_ctl + ".worldMatrix") blend_node = node.createBlendNode( [dm_node + ".outputRotate%s" % s for s in "XYZ"], [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori0_att) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node + ".output", self.div_cns[i] + ".rotate") elif i == self.settings["division"] - 1: dm_node = node.createDecomposeMatrixNode( self.ik1_ctl + ".worldMatrix") blend_node = node.createBlendNode( [dm_node + ".outputRotate%s" % s for s in "XYZ"], [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori1_att) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node + ".output", self.div_cns[i] + ".rotate") # Connections (Hooks) ------------------------------ pm.parentConstraint(self.scl_transforms[0], self.cnx0) pm.scaleConstraint(self.scl_transforms[0], self.cnx0) pm.parentConstraint(self.scl_transforms[-1], self.cnx1) pm.scaleConstraint(self.scl_transforms[-1], self.cnx1)
def addOperators(self): # 1 bone chain Upv ref ===================================================================================== self.ikHandleUpvRef = pri.addIkHandle( self.root, self.getName("ikHandleLegChainUpvRef"), self.armChainUpvRef, "ikSCsolver") pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef) pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True) # Visibilities ------------------------------------- # fk fkvis_node = nod.createReverseNode(self.blend_att) for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) if self.settings["ikTR"]: for shp in self.ikRot_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- att.setRotOrder(self.fk0_ctl, "XZY") att.setRotOrder(self.fk1_ctl, "XYZ") att.setRotOrder(self.fk2_ctl, "YZX") # att.setRotOrder(self.ik_ctl, "ZYX") att.setRotOrder(self.ik_ctl, "XYZ") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc] node = aop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk_ctl[0], self.fk_ctl[1], self.fk_ref, self.length0, self.length1, self.negate) if self.settings["ikTR"]: #connect the control inputs outEff_dm = node.listConnections(c=True)[-1][1] outEff_dm.attr("outputTranslate") >> self.ikRot_npo.attr( "translate") outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale") dm_node = nod.createDecomposeMatrixNode(node.attr("outB")) dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate") #rotation # intM_node = aop.gear_intmatrix_op(node.attr("outEff"), self.ikRot_ctl.attr("worldMatrix"), node.attr("blend")) # mulM_node = aop.gear_mulmatrix_op(intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix")) # dm_node = nod.createDecomposeMatrixNode(mulM_node.attr("output")) mulM_node = aop.gear_mulmatrix_op( self.ikRot_ctl.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) intM_node = aop.gear_intmatrix_op(node.attr("outEff"), mulM_node.attr("output"), node.attr("blend")) dm_node = nod.createDecomposeMatrixNode(intM_node.attr("output")) dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate") #scale: this fix the scalin popping issue intM_node = aop.gear_intmatrix_op(self.fk2_ctl.attr("worldMatrix"), self.ik_ctl.attr("worldMatrix"), node.attr("blend")) mulM_node = aop.gear_mulmatrix_op( intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix")) dm_node = nod.createDecomposeMatrixNode(mulM_node.attr("output")) dm_node.attr("outputScale") >> self.eff_loc.attr("scale") pm.connectAttr(self.blend_att, node + ".blend") pm.connectAttr(self.roll_att, node + ".roll") pm.connectAttr(self.scale_att, node + ".scaleA") pm.connectAttr(self.scale_att, node + ".scaleB") pm.connectAttr(self.maxstretch_att, node + ".maxstretch") pm.connectAttr(self.slide_att, node + ".slide") pm.connectAttr(self.softness_att, node + ".softness") pm.connectAttr(self.reverse_att, node + ".reverse") # Twist references --------------------------------- pm.pointConstraint(self.mid_ctl, self.tws1_npo, maintainOffset=False) pm.scaleConstraint(self.mid_ctl, self.tws1_npo, maintainOffset=False) pm.orientConstraint(self.mid_ctl, self.tws1_npo, maintainOffset=False) node = aop.gear_mulmatrix_op(self.eff_loc.attr("worldMatrix"), self.root.attr("worldInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.tws2_npo.attr("translate")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate")) node = aop.gear_mulmatrix_op(self.eff_loc.attr("worldMatrix"), self.tws2_rot.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".output", dm_node + ".inputMatrix") att.setRotOrder(self.tws2_rot, "XYZ") pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate") self.tws0_rot.setAttr("sx", .001) self.tws2_rot.setAttr("sx", .001) add_node = nod.createAddNode(self.roundness_att, .001) pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx")) pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX") #Roll Shoulder aop.splineIK(self.getName("rollRef"), self.rollRef, parent=self.root, cParent=self.bone0) # Volume ------------------------------------------- distA_node = nod.createDistNode(self.tws0_loc, self.tws1_loc) distB_node = nod.createDistNode(self.tws1_loc, self.tws2_loc) add_node = nod.createAddNode(distA_node + ".distance", distB_node + ".distance") div_node = nod.createDivNode(add_node + ".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix") div_node2 = nod.createDivNode(div_node + ".outputX", dm_node + ".outputScaleX") self.volDriver_att = div_node2 + ".outputX" # Divisions ---------------------------------------- # at 0 or 1 the division will follow exactly the rotation of the controler.. and we wont have this nice tangent + roll for i, div_cns in enumerate(self.div_cns): if i < (self.settings["div0"] + 1): perc = i * .5 / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = .49 elif i < (self.settings["div0"] + 3): perc = .50 elif i < (self.settings["div0"] + 4): perc = .51 else: perc = .5 + (i - self.settings["div0"] - 3.0) * .5 / (self.settings["div1"] + 1.0) perc = max(.001, min(.990, perc)) # Roll if self.negate: node = aop.gear_rollsplinekine_op( div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1 - perc, 40) else: node = aop.gear_rollsplinekine_op( div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc, 40) pm.connectAttr(self.resample_att, node + ".resample") pm.connectAttr(self.absolute_att, node + ".absolute") # Squash n Stretch node = aop.gear_squashstretch2_op(div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, node + ".blend") pm.connectAttr(self.volDriver_att, node + ".driver") pm.connectAttr(self.st_att[i], node + ".stretch") pm.connectAttr(self.sq_att[i], node + ".squash") # match IK/FK ref pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True) pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True) return
def addOperators(self): # 1 bone chain Upv ref ===================================================================================== self.ikHandleUpvRef = pri.addIkHandle(self.root, self.getName("ikHandleLegChainUpvRef"), self.armChainUpvRef, "ikSCsolver") pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef) pm.parentConstraint( self.armChainUpvRef[0], self.upv_cns, mo=True) # Visibilities ------------------------------------- # fk fkvis_node = nod.createReverseNode(self.blend_att) for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility")) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility")) # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) if self.settings["ikTR"]: for shp in self.ikRot_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- att.setRotOrder(self.fk0_ctl, "XZY") att.setRotOrder(self.fk1_ctl, "XYZ") att.setRotOrder(self.fk2_ctl, "YZX") # att.setRotOrder(self.ik_ctl, "ZYX") att.setRotOrder(self.ik_ctl, "XYZ") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc] node = aop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk_ctl[0], self.fk_ctl[1], self.fk_ref, self.length0, self.length1, self.negate) if self.settings["ikTR"]: #connect the control inputs outEff_dm = node.listConnections(c=True)[-1][1] outEff_dm.attr("outputTranslate") >> self.ikRot_npo.attr("translate") outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale") dm_node = nod.createDecomposeMatrixNode(node.attr("outB")) dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate") #rotation mulM_node = aop.gear_mulmatrix_op(self.ikRot_ctl.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) intM_node = aop.gear_intmatrix_op(node.attr("outEff"), mulM_node.attr("output"), node.attr("blend")) dm_node = nod.createDecomposeMatrixNode(intM_node.attr("output")) dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate") tra.matchWorldTransform(self.fk2_ctl, self.ikRot_cns) #scale: this fix the scalin popping issue intM_node = aop.gear_intmatrix_op(self.fk2_ctl.attr("worldMatrix"), self.ik_ctl_ref.attr("worldMatrix"), node.attr("blend")) mulM_node = aop.gear_mulmatrix_op(intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix")) dm_node = nod.createDecomposeMatrixNode(mulM_node.attr("output")) dm_node.attr("outputScale") >> self.eff_loc.attr("scale") pm.connectAttr(self.blend_att, node+".blend") if self.negate: mulVal = -1 else: mulVal = 1 nod.createMulNode(self.roll_att, mulVal, node+".roll") pm.connectAttr(self.scale_att, node+".scaleA") pm.connectAttr(self.scale_att, node+".scaleB") pm.connectAttr(self.maxstretch_att, node+".maxstretch") pm.connectAttr(self.slide_att, node+".slide") pm.connectAttr(self.softness_att, node+".softness") pm.connectAttr(self.reverse_att, node+".reverse") # Twist references --------------------------------- node = aop.gear_mulmatrix_op(self.eff_loc.attr("worldMatrix"), self.root.attr("worldInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node+".output", dm_node+".inputMatrix") pm.connectAttr(dm_node+".outputTranslate", self.tws2_npo.attr("translate")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node+".output", dm_node+".inputMatrix") pm.connectAttr(dm_node+".outputRotate", self.tws2_npo.attr("rotate")) #spline IK for twist jnts self.ikhArmTwist, self.armTwistCrv = aop.splineIK(self.getName("armTwist"), self.armTwistChain, parent=self.root, cParent=self.bone0 ) self.ikhForearmTwist, self.forearmTwistCrv = aop.splineIK(self.getName("forearmTwist"), self.forearmTwistChain, parent=self.root, cParent=self.bone1 ) #references self.ikhArmRef, self.tmpCrv = aop.splineIK(self.getName("armRollRef"), self.armRollRef, parent=self.root, cParent=self.bone0 ) self.ikhForearmRef, self.tmpCrv = aop.splineIK(self.getName("forearmRollRef"), self.forearmRollRef, parent=self.root, cParent=self.eff_loc ) self.ikhAuxTwist, self.tmpCrv = aop.splineIK(self.getName("auxTwist"), self.auxTwistChain, parent=self.root, cParent=self.eff_loc ) #setting connexions for ikhArmTwist self.ikhArmTwist.attr("dTwistControlEnable").set(True) self.ikhArmTwist.attr("dWorldUpType").set(4) self.ikhArmTwist.attr("dWorldUpAxis").set(3) self.ikhArmTwist.attr("dWorldUpVectorZ").set(1.0) self.ikhArmTwist.attr("dWorldUpVectorY").set(0.0) self.ikhArmTwist.attr("dWorldUpVectorEndZ").set(1.0) self.ikhArmTwist.attr("dWorldUpVectorEndY").set(0.0) pm.connectAttr(self.armRollRef[0].attr("worldMatrix[0]"), self.ikhArmTwist.attr("dWorldUpMatrix")) pm.connectAttr(self.bone0.attr("worldMatrix[0]"), self.ikhArmTwist.attr("dWorldUpMatrixEnd")) #setting connexions for ikhAuxTwist self.ikhAuxTwist.attr("dTwistControlEnable").set(True) self.ikhAuxTwist.attr("dWorldUpType").set(4) self.ikhAuxTwist.attr("dWorldUpAxis").set(3) self.ikhAuxTwist.attr("dWorldUpVectorZ").set(1.0) self.ikhAuxTwist.attr("dWorldUpVectorY").set(0.0) self.ikhAuxTwist.attr("dWorldUpVectorEndZ").set(1.0) self.ikhAuxTwist.attr("dWorldUpVectorEndY").set(0.0) pm.connectAttr(self.forearmRollRef[0].attr("worldMatrix[0]"), self.ikhAuxTwist.attr("dWorldUpMatrix")) pm.connectAttr(self.eff_loc.attr("worldMatrix[0]"), self.ikhAuxTwist.attr("dWorldUpMatrixEnd")) pm.connectAttr(self.auxTwistChain[1].attr("rx"), self.ikhForearmTwist.attr("twist")) pm.parentConstraint(self.bone1, self.aux_npo, maintainOffset=True) #scale arm length for twist chain (not the squash and stretch) arclen_node = pm.arclen(self.armTwistCrv, ch=True) alAttrArm = arclen_node.attr("arcLength") muldiv_nodeArm = pm.createNode("multiplyDivide") pm.connectAttr(arclen_node.attr("arcLength"), muldiv_nodeArm.attr("input1X")) muldiv_nodeArm.attr("input2X").set(alAttrArm.get()) muldiv_nodeArm.attr("operation").set(2) for jnt in self.armTwistChain: pm.connectAttr(muldiv_nodeArm.attr("outputX"),jnt.attr("sx")) #scale forearm length for twist chain (not the squash and stretch) arclen_node = pm.arclen(self.forearmTwistCrv, ch=True) alAttrForearm = arclen_node.attr("arcLength") muldiv_nodeForearm = pm.createNode("multiplyDivide") pm.connectAttr(arclen_node.attr("arcLength"), muldiv_nodeForearm.attr("input1X")) muldiv_nodeForearm.attr("input2X").set(alAttrForearm.get()) muldiv_nodeForearm.attr("operation").set(2) for jnt in self.forearmTwistChain: pm.connectAttr(muldiv_nodeForearm.attr("outputX"),jnt.attr("sx")) #scale compensation for the first twist join dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix[0]"), dm_node.attr("inputMatrix")) pm.connectAttr(dm_node.attr("outputScale"), self.armTwistChain[0].attr("inverseScale")) pm.connectAttr(dm_node.attr("outputScale"), self.forearmTwistChain[0].attr("inverseScale")) #tangent controls muldiv_node = pm.createNode("multiplyDivide") muldiv_node.attr("input2X").set(-1) pm.connectAttr(self.tws1A_npo.attr("rz"), muldiv_node.attr("input1X")) muldiv_nodeBias = pm.createNode("multiplyDivide") pm.connectAttr(muldiv_node.attr("outputX"), muldiv_nodeBias.attr("input1X")) pm.connectAttr(self.roundness_att, muldiv_nodeBias.attr("input2X")) pm.connectAttr(muldiv_nodeBias.attr("outputX"), self.tws1A_loc.attr("rz") ) if self.negate: axis = "xz" else: axis = "-xz" aop.aimCns(self.tws1A_npo, self.tws0_loc, axis=axis, wupType=2, wupVector=[0,0,1], wupObject=self.mid_ctl, maintainOffset=False) aop.aimCns(self.forearmTangentB_loc, self.forearmTangentA_npo, axis=axis, wupType=2, wupVector=[0,0,1], wupObject=self.mid_ctl, maintainOffset=False) pm.pointConstraint(self.eff_loc, self.forearmTangentB_loc) muldiv_node = pm.createNode("multiplyDivide") muldiv_node.attr("input2X").set(-1) pm.connectAttr(self.tws1B_npo.attr("rz"), muldiv_node.attr("input1X")) muldiv_nodeBias = pm.createNode("multiplyDivide") pm.connectAttr(muldiv_node.attr("outputX"), muldiv_nodeBias.attr("input1X")) pm.connectAttr(self.roundness_att, muldiv_nodeBias.attr("input2X")) pm.connectAttr(muldiv_nodeBias.attr("outputX"), self.tws1B_loc.attr("rz") ) if self.negate: axis = "-xz" else: axis = "xz" aop.aimCns(self.tws1B_npo, self.tws2_loc, axis=axis, wupType=2, wupVector=[0,0,1], wupObject=self.mid_ctl, maintainOffset=False) aop.aimCns(self.armTangentA_loc, self.armTangentB_npo, axis=axis, wupType=2, wupVector=[0,0,1], wupObject=self.mid_ctl, maintainOffset=False) # Volume ------------------------------------------- distA_node = nod.createDistNode(self.tws0_loc, self.tws1_loc) distB_node = nod.createDistNode(self.tws1_loc, self.tws2_loc) add_node = nod.createAddNode(distA_node+".distance", distB_node+".distance") div_node = nod.createDivNode(add_node+".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node+".inputMatrix") div_node2 = nod.createDivNode(div_node+".outputX", dm_node+".outputScaleX") self.volDriver_att = div_node2+".outputX" # connecting tangent scaele compensation after volume to aboid duplicate some nodes ------------------------------ distA_node = nod.createDistNode(self.tws0_loc, self.mid_ctl) distB_node = nod.createDistNode(self.mid_ctl, self.tws2_loc) div_nodeArm = nod.createDivNode(distA_node+".distance", dm_node.attr("outputScaleX")) div_node2 = nod.createDivNode(div_nodeArm+".outputX", distA_node.attr("distance").get()) pm.connectAttr(div_node2.attr("outputX"), self.tws1A_loc.attr("sx")) pm.connectAttr(div_node2.attr("outputX"), self.armTangentA_loc.attr("sx")) div_nodeForearm = nod.createDivNode(distB_node+".distance", dm_node.attr("outputScaleX")) div_node2 = nod.createDivNode(div_nodeForearm+".outputX", distB_node.attr("distance").get()) pm.connectAttr(div_node2.attr("outputX"), self.tws1B_loc.attr("sx")) pm.connectAttr(div_node2.attr("outputX"), self.forearmTangentB_loc.attr("sx")) #conection curve aop.gear_curvecns_op(self.armTwistCrv, [ self.armTangentA_loc, self.armTangentA_ctl, self.armTangentB_ctl,self.elbowTangent_ctl ]) aop.gear_curvecns_op(self.forearmTwistCrv, [ self.elbowTangent_ctl, self.forearmTangentA_ctl, self.forearmTangentB_ctl,self.forearmTangentB_loc ]) #Tangent controls vis for shp in self.armTangentA_ctl.getShapes(): pm.connectAttr( self.tangentVis_att, shp.attr("visibility")) for shp in self.armTangentB_ctl.getShapes(): pm.connectAttr( self.tangentVis_att, shp.attr("visibility")) for shp in self.forearmTangentA_ctl.getShapes(): pm.connectAttr( self.tangentVis_att, shp.attr("visibility")) for shp in self.forearmTangentB_ctl.getShapes(): pm.connectAttr( self.tangentVis_att, shp.attr("visibility")) for shp in self.elbowTangent_ctl.getShapes(): pm.connectAttr( self.tangentVis_att, shp.attr("visibility")) # Divisions ---------------------------------------- # at 0 or 1 the division will follow exactly the rotation of the controler.. and we wont have this nice tangent + roll for i, div_cns in enumerate(self.div_cns): if i < (self.settings["div0"]+2): mulmat_node = aop.gear_mulmatrix_op(self.armTwistChain[i]+".worldMatrix", div_cns+".parentInverseMatrix") lastArmDiv = div_cns else: mulmat_node = aop.gear_mulmatrix_op(self.forearmTwistChain[i-(self.settings["div0"]+2)]+".worldMatrix", div_cns+".parentInverseMatrix") lastForeDiv = div_cns dm_node = nod.createDecomposeMatrixNode(mulmat_node+".output") pm.connectAttr(dm_node+".outputTranslate", div_cns+".t") pm.connectAttr(dm_node+".outputRotate", div_cns+".r") # Squash n Stretch node = aop.gear_squashstretch2_op(div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, node+".blend") pm.connectAttr(self.volDriver_att, node+".driver") pm.connectAttr(self.st_att[i], node+".stretch") pm.connectAttr(self.sq_att[i], node+".squash") #force translation for last loc arm and foreamr aop.gear_mulmatrix_op(self.elbowTangent_ctl.worldMatrix,lastArmDiv.parentInverseMatrix, lastArmDiv, "t" ) aop.gear_mulmatrix_op(self.tws2_loc.worldMatrix,lastForeDiv.parentInverseMatrix, lastForeDiv, "t" ) # return # NOTE: next line fix the issue on meters. # This is special case becasuse the IK solver from mGear use the scale as lenght and we have shear # TODO: check for a more clean and elegant solution instead of re-match the world matrix again tra.matchWorldTransform(self.fk_ctl[0], self.match_fk0_off) tra.matchWorldTransform(self.fk_ctl[1], self.match_fk1_off) tra.matchWorldTransform(self.fk_ctl[0], self.match_fk0) tra.matchWorldTransform(self.fk_ctl[1], self.match_fk1) # match IK/FK ref pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True) pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True) if self.settings["ikTR"]: tra.matchWorldTransform(self.ikRot_ctl,self.match_ikRot ) tra.matchWorldTransform(self.fk_ctl[2], self.match_fk2 )
def addOperators(self): # Tangent position --------------------------------- # common part d = vec.getDistance(self.guide.apos[0], self.guide.apos[1]) dist_node = nod.createDistNode(self.ik0_ctl, self.ik1_ctl) rootWorld_node = nod.createDecomposeMatrixNode(self.root.attr("worldMatrix")) div_node = nod.createDivNode(dist_node+".distance", rootWorld_node+".outputScaleX") div_node = nod.createDivNode(div_node+".outputX", d) # tan0 mul_node = nod.createMulNode(self.tan0_att, self.tan0_npo.getAttr("ty")) res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX") pm.connectAttr( res_node+".outputX", self.tan0_npo.attr("ty")) # tan1 mul_node = nod.createMulNode(self.tan1_att, self.tan1_npo.getAttr("ty")) res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX") pm.connectAttr( res_node+".outputX", self.tan1_npo.attr("ty")) # Curves ------------------------------------------- op = aop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5, .5, .5) pm.connectAttr(self.position_att, op+".position") pm.connectAttr(self.maxstretch_att, op+".maxstretch") pm.connectAttr(self.maxsquash_att, op+".maxsquash") pm.connectAttr(self.softness_att, op+".softness") # Volume driver ------------------------------------ crv_node = nod.createCurveInfoNode(self.slv_crv) # Division ----------------------------------------- for i in range(self.settings["division"]): # References u = i / (self.settings["division"] - 1.0) cns = aop.pathCns(self.div_cns[i], self.slv_crv, False, u, True) cns.setAttr("frontAxis", 1)# front axis is 'Y' cns.setAttr("upAxis", 0)# front axis is 'X' # Roll intMatrix = aop.gear_intmatrix_op(self.ik0_ctl+".worldMatrix", self.ik1_ctl+".worldMatrix", u) dm_node = nod.createDecomposeMatrixNode(intMatrix+".output") pm.connectAttr(dm_node+".outputRotate", self.twister[i].attr("rotate")) pm.parentConstraint(self.twister[i], self.ref_twist[i], maintainOffset=True) pm.connectAttr(self.ref_twist[i]+".translate", cns+".worldUpVector") # Squash n Stretch op = aop.gear_squashstretch2_op(self.fk_npo[i], self.root, pm.arclen(self.slv_crv), "y") pm.connectAttr(self.volume_att, op+".blend") pm.connectAttr(crv_node+".arcLength", op+".driver") pm.connectAttr(self.st_att[i], op+".stretch") pm.connectAttr(self.sq_att[i], op+".squash") # scl compensation if i == 0: dm_node = nod.createDecomposeMatrixNode(self.root+".worldMatrix") div_node = nod.createDivNode([1,1,1], [dm_node+".outputScaleX", dm_node+".outputScaleY", dm_node+".outputScaleZ"]) pm.connectAttr(div_node+".output", self.scl_npo[i]+".scale") elif i == 1: div_node = nod.createDivNode([1,1,1], [self.fk_npo[i-1]+".sx", self.fk_npo[i-1]+".sy", self.fk_npo[i-1]+".sz"]) pm.connectAttr(div_node+".output", self.scl_npo[i]+".scale") else: div_node = nod.createDivNode([1,1,1], [self.fk_npo[i-1]+".sx", self.fk_npo[i-1]+".sy", self.fk_npo[i-1]+".sz"]) pm.connectAttr(div_node+".output", self.scl_npo[i]+".scale") # Controlers if i == 0: mulmat_node = aop.gear_mulmatrix_op(self.div_cns[i].attr("worldMatrix"), self.scl_npo[0].attr("worldInverseMatrix")) else: mulmat_node = aop.gear_mulmatrix_op(self.div_cns[i].attr("worldMatrix"), self.div_cns[i - 1].attr("worldInverseMatrix")) dm_node = nod.createDecomposeMatrixNode(mulmat_node+".output") pm.connectAttr(dm_node+".outputTranslate", self.fk_npo[i].attr("t")) pm.connectAttr(dm_node+".outputRotate", self.fk_npo[i].attr("r")) # Orientation Lock if i == 0 : dm_node = nod.createDecomposeMatrixNode(self.ik0_ctl+".worldMatrix") blend_node = nod.createBlendNode([dm_node+".outputRotate%s"%s for s in "XYZ"], [cns+".rotate%s"%s for s in "XYZ"], self.lock_ori0_att) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node+".output", self.div_cns[i]+".rotate") elif i == self.settings["division"] - 1 : dm_node = nod.createDecomposeMatrixNode(self.ik1_ctl+".worldMatrix") blend_node = nod.createBlendNode([dm_node+".outputRotate%s"%s for s in "XYZ"], [cns+".rotate%s"%s for s in "XYZ"], self.lock_ori1_att) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node+".output", self.div_cns[i]+".rotate") # Connections (Hooks) ------------------------------ pm.pointConstraint(self.div_cns[0], self.cnx0) pm.orientConstraint(self.div_cns[0], self.cnx0) pm.pointConstraint(self.fk_ctl[-1], self.cnx1) pm.orientConstraint(self.fk_ctl[-1], self.cnx1)