def addOperatorsOrientationLock(self, i, cns): # Orientation Lock if i == 0: dm_node = node.createDecomposeMatrixNode( self.ik_ctl[0] + ".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) # 0) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node + ".output", self.div_cns[i] + ".rotate") elif i == len(self.fk_ctl) - 1: dm_node = node.createDecomposeMatrixNode( self.ik_ctl[-1] + ".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) # 1) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node + ".output", self.div_cns[i] + ".rotate")
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. """ inc = 1.0 / (len(self.guide.apos) - 1) val = 0.0 for i, loc in enumerate(self.locList): blendNode = node.createPairBlend(self.npoList[i], self.meta_ctl, blender=val) if self.settings["intRotation"]: pm.connectAttr(blendNode.attr("outRotate"), loc.attr("rotate")) if self.settings["intTranslation"]: pm.connectAttr(blendNode.attr("outTranslate"), loc.attr("translate")) if self.settings["intScale"]: scaleA = [ self.meta_ctl.attr("sx"), self.meta_ctl.attr("sy"), self.meta_ctl.attr("sz") ] scaleB = [ self.npoList[i].attr("sx"), self.npoList[i].attr("sy"), self.npoList[i].attr("sz") ] scaleBlend = node.createBlendNode(scaleA, scaleB, val) pm.connectAttr(scaleBlend.attr("output"), loc.attr("scale")) val += inc
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) if i == 0: # we add extra 10% to the first vertebra u = (1.0 / (self.settings["division"] - 1.0)) / 10 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.hip_lvl, self.cnx0) pm.scaleConstraint(self.hip_lvl, self.cnx0) pm.parentConstraint(self.scl_transforms[-1], self.cnx1) pm.scaleConstraint(self.scl_transforms[-1], self.cnx1)
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, 0.5, 0.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.divisions): # References u = i / (self.divisions - 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", 0.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.divisions - 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. """ # Visibilities ------------------------------------- # ik if self.settings["useRollCtl"]: for shp in self.roll_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for bk_ctl in self.bk_ctl: for shp in bk_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.heel_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.tip_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # Roll / Bank -------------------------------------- if self.settings["useRollCtl"]: # Using the controler self.roll_att = self.roll_ctl.attr("rz") self.bank_att = self.roll_ctl.attr("rx") clamp_node = node.createClampNode( [self.roll_att, self.bank_att, self.bank_att], [0, -180, 0], [180, 0, 180]) inAdd_nod = node.createAddNode( clamp_node + ".outputB", pm.getAttr(self.in_piv.attr("rx")) * self.n_factor) pm.connectAttr(clamp_node + ".outputR", self.heel_loc.attr("rz")) pm.connectAttr(clamp_node + ".outputG", self.out_piv.attr("rx")) pm.connectAttr(inAdd_nod + ".output", self.in_piv.attr("rx")) # Reverse Controler offset ------------------------- angle_outputs = node.createAddNodeMulti(self.angles_att) for i, bk_loc in enumerate(reversed(self.bk_loc)): if i == 0: # First input = self.roll_att min_input = self.angles_att[i] elif i == len(self.angles_att): # Last sub_nod = node.createSubNode(self.roll_att, angle_outputs[i - 1]) input = sub_nod + ".output" min_input = -360 else: # Others sub_nod = node.createSubNode(self.roll_att, angle_outputs[i - 1]) input = sub_nod + ".output" min_input = self.angles_att[i] clamp_node = node.createClampNode(input, min_input, 0) add_node = node.createAddNode(clamp_node + ".outputR", bk_loc.getAttr("rz")) pm.connectAttr(add_node + ".output", bk_loc.attr("rz")) # Reverse compensation ----------------------------- for i, fk_loc in enumerate(self.fk_loc): bk_ctl = self.bk_ctl[-i - 1] bk_loc = self.bk_loc[-i - 1] fk_ctl = self.fk_ctl[i] # Inverse Rotorder applyop.gear_inverseRotorder_op(bk_loc, fk_ctl) pm.connectAttr(fk_ctl.attr("ro"), fk_loc.attr("ro")) attribute.lockAttribute(bk_loc, "ro") # Compensate the backward rotation # ik # addx_node = node.createAddNode(bk_loc.attr("rx"), bk_loc.attr("rx")) # addy_node = node.createAddNode(bk_loc.attr("ry"), bk_loc.attr("ry")) # addz_node = node.createAddNode(bk_loc.attr("rz"), bk_loc.attr("rz")) addz_node = node.createAddNode( bk_loc.attr("rz"), -bk_loc.getAttr("rz") - fk_loc.getAttr("rz")) neg_node = node.createMulNode([bk_loc.attr("rx"), bk_loc.attr("ry"), addz_node + ".output"], [-1, -1, -1]) ik_outputs = [neg_node + ".outputX", neg_node + ".outputY", neg_node + ".outputZ"] # fk fk_outputs = [0, 0, fk_loc.getAttr("rz")] # blend blend_node = node.createBlendNode(ik_outputs, fk_outputs, self.blend_att) pm.connectAttr(blend_node + ".output", fk_loc.attr("rotate")) 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. """ # 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") # Division ----------------------------------------- rootWorld_node = node.createDecomposeMatrixNode( self.root.attr("worldMatrix")) for i in range(self.settings["fkNb"]): # References u = i / (self.settings["fkNb"] - 1.0) if i == 0: # we add extra 10% to the first position u = (1.0 / (self.settings["fkNb"] - 1.0)) / 10 cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u, True) cns.setAttr("frontAxis", 0) # front axis is 'X' cns.setAttr("upAxis", 2) # front axis is 'Z' # Roll intMatrix = applyop.gear_intmatrix_op( self.ik_ctl[0] + ".worldMatrix", self.ik_ctl[-1] + ".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" ]) # 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.ik_ctl[0] + ".worldMatrix") blend_node = node.createBlendNode( [dm_node + ".outputRotate%s" % s for s in "XYZ"], [cns + ".rotate%s" % s for s in "XYZ"], 0) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node + ".output", self.div_cns[i] + ".rotate") elif i == self.settings["fkNb"] - 1: dm_node = node.createDecomposeMatrixNode(self.ik_ctl[-1] + ".worldMatrix") blend_node = node.createBlendNode( [dm_node + ".outputRotate%s" % s for s in "XYZ"], [cns + ".rotate%s" % s for s in "XYZ"], 0) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node + ".output", self.div_cns[i] + ".rotate")
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[1], self.guide.apos[-2]) 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 ----------------------------------------- tangents = [None, "tan0", "tan1"] for i in range(self.settings["division"]): # References u = i / (self.settings["division"] - 1.0) # check the indx to calculate mid point based on number of division # we want to use the same spine for mannequin and metahuman spine if self.settings["division"] == 4 and i in [1, 2]: u_param = curve.getCurveParamAtPosition( self.slv_crv, self.guide.pos[tangents[i]])[0] cnsType = True elif self.settings["division"] == 3 and i in [1]: u_param = curve.getCurveParamAtPosition( self.slv_crv, self.guide.pos[tangents[i]])[0] cnsType = True else: u_param = u cnsType = False cns = applyop.pathCns(self.div_cns[i], self.slv_crv, cnsType, u_param, 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") # change parent after operators applied pm.parent(self.scl_transforms[-1], self.fk_ctl[-1]) # Connections (Hooks) ------------------------------ pm.parentConstraint(self.pelvis_lvl, self.cnx0) pm.scaleConstraint(self.pelvis_lvl, self.cnx0) transform.matchWorldTransform(self.scl_transforms[-1], self.cnx1) t = transform.setMatrixPosition(transform.getTransform(self.cnx1), self.guide.apos[-1]) self.cnx1.setMatrix(t, worldSpace=True) pm.parentConstraint(self.scl_transforms[-1], self.cnx1, mo=True) pm.scaleConstraint(self.scl_transforms[-1], self.cnx1)