def addObjects(self): self.root = self.addRoot() vTemp = transform.getOffsetPosition(self.root, [0, 0, 1]) self.sizeRef = self.addLoc("sizeRef", self.root, vTemp) pm.delete(self.sizeRef.getShapes()) attribute.lockAttribute(self.sizeRef)
def initialHierarchy(self): mgear.log("Initial Hierarchy") # -------------------------------------------------- # Model self.model = pri.addTransformFromPos(None, self.options["rig_name"]) att.lockAttribute(self.model) # -------------------------------------------------- # Global Ctl self.global_ctl = self.addCtl(self.model, "global_C0_ctl", dt.Matrix(), self.options["C_color_fk"], "crossarrow", w=10) # -------------------------------------------------- # INFOS self.isRig_att = att.addAttribute(self.model, "is_rig", "bool", True) self.rigName_att = att.addAttribute(self.model, "rig_name", "string", self.options["rig_name"]) self.user_att = att.addAttribute(self.model, "user", "string", getpass.getuser()) self.isWip_att = att.addAttribute(self.model, "wip", "bool", self.options["mode"] != 0) self.date_att = att.addAttribute(self.model, "date", "string", str(datetime.datetime.now())) self.mayaVersion_att = att.addAttribute( self.model, "maya_version", "string", str(mel.eval("getApplicationVersionAsFloat"))) self.gearVersion_att = att.addAttribute(self.model, "gear_version", "string", mgear.getVersion()) self.synoptic_att = att.addAttribute(self.model, "synoptic", "string", str(self.options["synoptic"])) self.comments_att = att.addAttribute(self.model, "comments", "string", str(self.options["comments"])) self.ctlVis_att = att.addAttribute(self.model, "ctl_vis", "bool", True) self.shdVis_att = att.addAttribute(self.model, "shd_vis", "bool", False) self.qsA_att = att.addAttribute(self.model, "quickselA", "string", "") self.qsB_att = att.addAttribute(self.model, "quickselB", "string", "") self.qsC_att = att.addAttribute(self.model, "quickselC", "string", "") self.qsD_att = att.addAttribute(self.model, "quickselD", "string", "") self.qsE_att = att.addAttribute(self.model, "quickselE", "string", "") self.qsF_att = att.addAttribute(self.model, "quickselF", "string", "") # -------------------------------------------------- # UI SETUP AND ANIM self.oglLevel_att = att.addAttribute(self.model, "ogl_level", "long", 0, None, None, 0, 3) # -------------------------------------------------- # Basic set of null if self.options["shadow_rig"]: self.shd_org = pri.addTransformFromPos(self.model, "shd_org") connectAttr(self.shdVis_att, self.shd_org.attr("visibility"))
def finalize(self): """Finalize and clean the rig builing.""" # locking the attributes for all the ctl parents that are not ctl # itself. for t in self.transform2Lock: attribute.lockAttribute(t) return
def initialHierarchy(self): """ Build the initial hierarchy of the rig. Create the rig model, the main properties, and a couple of base organisation nulls. Get the global size of the rig. """ mgear.log("Initial Hierarchy") # -------------------------------------------------- # Model self.model = pri.addTransformFromPos(None, self.options["rig_name"]) att.lockAttribute(self.model) # -------------------------------------------------- # Global Ctl self.global_ctl = self.addCtl(self.model, "global_C0_ctl", dt.Matrix(), self.options["C_color_fk"], "crossarrow", w=10) att.setRotOrder(self.global_ctl, "ZXY") # -------------------------------------------------- # Setup in world Space self.setupWS = pri.addTransformFromPos(self.model, "setup") att.lockAttribute(self.setupWS) # -------------------------------------------------- # INFOS self.isRig_att = att.addAttribute(self.model, "is_rig", "bool", True) self.rigName_att = att.addAttribute(self.model, "rig_name", "string", self.options["rig_name"]) self.user_att = att.addAttribute(self.model, "user", "string", getpass.getuser()) self.isWip_att = att.addAttribute(self.model, "wip", "bool", self.options["mode"] != 0) self.date_att = att.addAttribute(self.model, "date", "string", str(datetime.datetime.now())) self.mayaVersion_att = att.addAttribute(self.model, "maya_version", "string", str(pm.mel.eval("getApplicationVersionAsFloat"))) self.gearVersion_att = att.addAttribute(self.model, "gear_version", "string", mgear.getVersion()) self.synoptic_att = att.addAttribute(self.model, "synoptic", "string", str(self.options["synoptic"])) self.comments_att = att.addAttribute(self.model, "comments", "string", str(self.options["comments"])) self.ctlVis_att = att.addAttribute(self.model, "ctl_vis", "bool", True) self.jntVis_att = att.addAttribute(self.model, "jnt_vis", "bool", True) self.qsA_att = att.addAttribute(self.model, "quickselA", "string", "") self.qsB_att = att.addAttribute(self.model, "quickselB", "string", "") self.qsC_att = att.addAttribute(self.model, "quickselC", "string", "") self.qsD_att = att.addAttribute(self.model, "quickselD", "string", "") self.qsE_att = att.addAttribute(self.model, "quickselE", "string", "") self.qsF_att = att.addAttribute(self.model, "quickselF", "string", "") self.rigGroups = self.model.addAttr( "rigGroups", at='message', m=1 ) self.rigPoses = self.model.addAttr( "rigPoses", at='message', m=1 ) # -------------------------------------------------- # Basic set of null if self.options["joint_rig"]: self.jnt_org = pri.addTransformFromPos(self.model, "jnt_org") pm.connectAttr(self.jntVis_att, self.jnt_org.attr("visibility"))
def addBlade(self, name, parentPos, parentDir): """ Add a blade object to the guide. This mehod can initialize the object or draw it. Blade object is a 3points curve to define a plan in the guide. Args: name (str): Local name of the element. parentPos (dagNode): The parent of the element. parentDir (dagNode): The direction constraint of the element. Returns: dagNode: The created blade curve. """ if name not in self.blades.keys(): self.blades[name] = vec.Blade( tra.getTransformFromPos(dt.Vector(0, 0, 0))) offset = False else: offset = True dist = .6 * self.root.attr("scaleX").get() blade = ico.guideBladeIcon(parent=parentPos, name=self.getName(name), lenX=dist, color=13, m=self.blades[name].transform) aim_cns = aop.aimCns(blade, parentDir, axis="xy", wupType=2, wupVector=[0, 1, 0], wupObject=self.root, maintainOffset=offset) pm.pointConstraint(parentPos, blade) offsetAttr = att.addAttribute(blade, "bladeRollOffset", "float", aim_cns.attr("offsetX").get()) pm.connectAttr(offsetAttr, aim_cns.attr("offsetX")) att.lockAttribute(blade) return blade
def initialHierarchy(self): mgear.log("Initial Hierarchy") # -------------------------------------------------- # Model self.model = pri.addTransformFromPos(None, self.options["rig_name"]) att.lockAttribute(self.model) # -------------------------------------------------- # Global Ctl self.global_ctl = self.addCtl(self.model, "global_C0_ctl", dt.Matrix(), self.options["C_color_fk"], "crossarrow", w=10) # -------------------------------------------------- # INFOS self.isRig_att = att.addAttribute(self.model, "is_rig", "bool", True) self.rigName_att = att.addAttribute(self.model, "rig_name", "string", self.options["rig_name"]) self.user_att = att.addAttribute(self.model, "user", "string", getpass.getuser()) self.isWip_att = att.addAttribute(self.model, "wip", "bool", self.options["mode"] != 0) self.date_att = att.addAttribute(self.model, "date", "string", str(datetime.datetime.now())) self.mayaVersion_att = att.addAttribute(self.model, "maya_version", "string", str(mel.eval("getApplicationVersionAsFloat"))) self.gearVersion_att = att.addAttribute(self.model, "gear_version", "string", mgear.getVersion()) self.synoptic_att = att.addAttribute(self.model, "synoptic", "string", str(self.options["synoptic"])) self.comments_att = att.addAttribute(self.model, "comments", "string", str(self.options["comments"])) self.ctlVis_att = att.addAttribute(self.model, "ctl_vis", "bool", True) self.shdVis_att = att.addAttribute(self.model, "shd_vis", "bool", False) self.qsA_att = att.addAttribute(self.model, "quickselA", "string", "") self.qsB_att = att.addAttribute(self.model, "quickselB", "string", "") self.qsC_att = att.addAttribute(self.model, "quickselC", "string", "") self.qsD_att = att.addAttribute(self.model, "quickselD", "string", "") self.qsE_att = att.addAttribute(self.model, "quickselE", "string", "") self.qsF_att = att.addAttribute(self.model, "quickselF", "string", "") # -------------------------------------------------- # UI SETUP AND ANIM self.oglLevel_att = att.addAttribute(self.model, "ogl_level", "long", 0, None, None, 0, 3) # -------------------------------------------------- # Basic set of null if self.options["shadow_rig"]: self.shd_org = pri.addTransformFromPos(self.model, "shd_org") connectAttr(self.shdVis_att, self.shd_org.attr("visibility"))
def addObjects(self): lockAttrs = ["tx", "ry", "rz"] self.root = self.addRoot() vTemp = tra.getOffsetPosition(self.root, [0, -3, 0.1]) self.knee = self.addLoc("knee", self.root, vTemp) att.lockAttribute(self.knee, lockAttrs) vTemp = tra.getOffsetPosition(self.root, [0, -6, 0]) self.ankle = self.addLoc("ankle", self.knee, vTemp) att.lockAttribute(self.ankle, lockAttrs) vTemp = tra.getOffsetPosition(self.root, [0, -9, .2]) self.foot = self.addLoc("foot", self.ankle, vTemp) att.lockAttribute(self.foot, lockAttrs) vTemp = tra.getOffsetPosition(self.root, [0, -9, 1]) self.eff = self.addLoc("eff", self.foot, vTemp) centers = [self.root, self.knee, self.ankle, self.foot, self.eff] self.dispcrv = self.addDispCurve("crv1", centers)
def addObjects(self): """Add all the objects needed to create the component.""" self.setup = primitive.addTransformFromPos(self.setupWS, self.getName("WS")) attribute.lockAttribute(self.setup) self.WIP = self.options["mode"] self.normal = self.getNormalFromPos(self.guide.apos) self.length0 = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) self.length1 = vector.getDistance(self.guide.apos[1], self.guide.apos[2]) self.length2 = vector.getDistance(self.guide.apos[2], self.guide.apos[3]) self.length3 = vector.getDistance(self.guide.apos[3], self.guide.apos[4]) # 3bones chain self.chain3bones = primitive.add2DChain( self.setup, self.getName("chain3bones%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # 2bones chain self.chain2bones = primitive.add2DChain( self.setup, self.getName("chain2bones%s_jnt"), self.guide.apos[0:3], self.normal, False, self.WIP) # Leg chain self.legBones = primitive.add2DChain(self.root, self.getName("legBones%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # Leg chain FK ref self.legBonesFK = primitive.add2DChain(self.root, self.getName("legFK%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # Leg chain IK ref self.legBonesIK = primitive.add2DChain(self.root, self.getName("legIK%s_jnt"), self.guide.apos[0:4], self.normal, False, self.WIP) # 1 bone chain for upv ref self.legChainUpvRef = primitive.add2DChain( self.root, self.getName("legUpvRef%s_jnt"), [self.guide.apos[0], self.guide.apos[3]], self.normal, False, self.WIP) # mid joints self.mid1_jnt = primitive.addJoint( self.legBones[0], self.getName("mid1_jnt"), self.legBones[1].getMatrix(worldSpace=True), self.WIP) self.mid1_jnt.attr("radius").set(3) self.mid1_jnt.setAttr("jointOrient", 0, 0, 0) self.mid2_jnt = primitive.addJoint( self.legBones[1], self.getName("mid2_jnt"), self.legBones[2].getMatrix(worldSpace=True), self.WIP) self.mid2_jnt.attr("radius").set(3) self.mid2_jnt.setAttr("jointOrient", 0, 0, 0) # base Controlers ----------------------------------- t = transform.getTransformFromPos(self.guide.apos[0]) self.root_npo = primitive.addTransform(self.root, self.getName("root_npo"), t) self.root_ctl = self.addCtl(self.root_npo, "root_ctl", t, self.color_fk, "circle", w=self.length0 / 6, tp=self.parentCtlTag) attribute.lockAttribute(self.root_ctl, ["sx", "sy", "sz", "v"]) # FK Controlers ----------------------------------- t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[1], self.normal, "xz", self.negate) self.fk0_npo = primitive.addTransform(self.root_ctl, self.getName("fk0_npo"), t) self.fk0_ctl = self.addCtl(self.fk0_npo, "fk0_ctl", t, self.color_fk, "cube", w=self.length0, h=self.size * .1, d=self.size * .1, po=datatypes.Vector( .5 * self.length0 * self.n_factor, 0, 0), tp=self.root_ctl) attribute.setKeyableAttributes(self.fk0_ctl) t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[2], self.normal, "xz", self.negate) self.fk1_npo = primitive.addTransform(self.fk0_ctl, self.getName("fk1_npo"), t) self.fk1_ctl = self.addCtl(self.fk1_npo, "fk1_ctl", t, self.color_fk, "cube", w=self.length1, h=self.size * .1, d=self.size * .1, po=datatypes.Vector( .5 * self.length1 * self.n_factor, 0, 0), tp=self.fk0_ctl) attribute.setKeyableAttributes(self.fk1_ctl) t = transform.getTransformLookingAt(self.guide.apos[2], self.guide.apos[3], self.normal, "xz", self.negate) self.fk2_npo = primitive.addTransform(self.fk1_ctl, self.getName("fk2_npo"), t) self.fk2_ctl = self.addCtl(self.fk2_npo, "fk2_ctl", t, self.color_fk, "cube", w=self.length2, h=self.size * .1, d=self.size * .1, po=datatypes.Vector( .5 * self.length2 * self.n_factor, 0, 0), tp=self.fk1_ctl) attribute.setKeyableAttributes(self.fk2_ctl) t = transform.getTransformLookingAt(self.guide.apos[3], self.guide.apos[4], self.normal, "xz", self.negate) self.fk3_npo = primitive.addTransform(self.fk2_ctl, self.getName("fk3_npo"), t) self.fk3_ctl = self.addCtl(self.fk3_npo, "fk3_ctl", t, self.color_fk, "cube", w=self.length3, h=self.size * .1, d=self.size * .1, po=datatypes.Vector( .5 * self.length3 * self.n_factor, 0, 0), tp=self.fk2_ctl) attribute.setKeyableAttributes(self.fk3_ctl) self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl, self.fk3_ctl] for x in self.fk_ctl: attribute.setInvertMirror(x, ["tx", "ty", "tz"]) # Mid Controlers ------------------------------------ self.knee_lvl = primitive.addTransform( self.root, self.getName("knee_lvl"), transform.getTransform(self.mid1_jnt)) self.knee_ctl = self.addCtl(self.knee_lvl, "knee_ctl", transform.getTransform(self.mid1_jnt), self.color_ik, "sphere", w=self.size * .2, tp=self.root_ctl) attribute.setInvertMirror(self.knee_ctl, ["tx", "ty", "tz"]) attribute.lockAttribute(self.knee_ctl, ["sx", "sy", "sz", "v"]) self.ankle_lvl = primitive.addTransform( self.root, self.getName("ankle_lvl"), transform.getTransform(self.mid2_jnt)) self.ankle_ctl = self.addCtl(self.ankle_lvl, "ankle_ctl", transform.getTransform(self.mid2_jnt), self.color_ik, "sphere", w=self.size * .2, tp=self.knee_ctl) attribute.setInvertMirror(self.ankle_ctl, ["tx", "ty", "tz"]) attribute.lockAttribute(self.ankle_ctl, ["sx", "sy", "sz", "v"]) # IK controls -------------------------------------------------------- # foot IK if self.settings["ikOri"]: t = transform.getTransformLookingAt(self.guide.pos["foot"], self.guide.pos["eff"], self.x_axis, "zx", False) else: t = transform.getTransformLookingAt(self.guide.apos[3], self.guide.apos[4], self.normal, "z-x", False) self.ik_cns = primitive.addTransform(self.root_ctl, self.getName("ik_cns"), t) self.ikcns_ctl = self.addCtl(self.ik_cns, "ikcns_ctl", t, self.color_ik, "null", w=self.size * .12, tp=self.ankle_ctl) attribute.setInvertMirror(self.ikcns_ctl, ["tx"]) attribute.lockAttribute(self.ikcns_ctl, ["sx", "sy", "sz", "v"]) self.ik_ctl = self.addCtl(self.ikcns_ctl, "ik_ctl", t, self.color_ik, "cube", w=self.size * .12, h=self.size * .12, d=self.size * .12, tp=self.ikcns_ctl) attribute.setKeyableAttributes(self.ik_ctl) attribute.setRotOrder(self.ik_ctl, "XZY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) attribute.lockAttribute(self.ik_ctl, ["sx", "sy", "sz", "v"]) # 2 bones ik layer self.ik2b_ikCtl_ref = primitive.addTransform( self.ik_ctl, self.getName("ik2B_A_ref"), t) self.ik2b_bone_ref = primitive.addTransform(self.chain3bones[3], self.getName("ik2B_B_ref"), t) self.ik2b_blend = primitive.addTransform(self.ik_ctl, self.getName("ik2B_blend"), t) self.roll_ctl = self.addCtl(self.ik2b_blend, "roll_ctl", t, self.color_ik, "crossarrow", w=self.length2 * .5 * self.n_factor, tp=self.ik_ctl) self.ik2b_ik_npo = primitive.addTransform( self.roll_ctl, self.getName("ik2B_ik_npo"), transform.getTransform(self.chain3bones[-1])) self.ik2b_ik_ref = primitive.addTransformFromPos( self.ik2b_ik_npo, self.getName("ik2B_ik_ref"), self.guide.pos["ankle"]) attribute.lockAttribute(self.roll_ctl, ["tx", "ty", "tz", "sx", "sy", "sz", "v"]) # upv v = self.guide.apos[2] - self.guide.apos[0] v = self.normal ^ v v.normalize() v *= self.size * .5 v += self.guide.apos[1] self.upv_lvl = primitive.addTransformFromPos(self.root, self.getName("upv_lvl"), v) self.upv_cns = primitive.addTransformFromPos(self.upv_lvl, self.getName("upv_cns"), v) self.upv_ctl = self.addCtl(self.upv_cns, "upv_ctl", transform.getTransform(self.upv_cns), self.color_ik, "diamond", w=self.size * .12, tp=self.ik_ctl) attribute.setInvertMirror(self.upv_ctl, ["tx"]) attribute.setKeyableAttributes(self.upv_ctl, ["tx", "ty", "tz"]) # Soft IK objects 3 bones chain -------------------------------- t = transform.getTransformLookingAt(self.guide.pos["root"], self.guide.pos["foot"], self.x_axis, "zx", False) self.aim_tra = primitive.addTransform(self.root_ctl, self.getName("aimSoftIK"), t) t = transform.getTransformFromPos(self.guide.pos["foot"]) self.wristSoftIK = primitive.addTransform(self.aim_tra, self.getName("wristSoftIK"), t) self.softblendLoc = primitive.addTransform( self.root, self.getName("softblendLoc"), t) # Soft IK objects 2 Bones chain ---------------------------- t = transform.getTransformLookingAt(self.guide.pos["root"], self.guide.pos["ankle"], self.x_axis, "zx", False) self.aim_tra2 = primitive.addTransform(self.root_ctl, self.getName("aimSoftIK2"), t) t = transform.getTransformFromPos(self.guide.pos["ankle"]) self.ankleSoftIK = primitive.addTransform(self.aim_tra2, self.getName("ankleSoftIK"), t) self.softblendLoc2 = primitive.addTransform( self.root, self.getName("softblendLoc2"), t) # References -------------------------------------- self.ik_ref = primitive.addTransform( self.ik_ctl, self.getName("ik_ref"), transform.getTransform(self.ik_ctl)) self.fk_ref = primitive.addTransform( self.fk_ctl[3], self.getName("fk_ref"), transform.getTransform(self.ik_ctl)) # twist references -------------------------------------- self.rollRef = primitive.add2DChain(self.root, self.getName("rollChain"), self.guide.apos[:2], self.normal, False, self.WIP) self.tws0_loc = primitive.addTransform( self.rollRef[0], self.getName("tws0_loc"), transform.getTransform(self.legBones[0])) self.tws0_rot = primitive.addTransform( self.tws0_loc, self.getName("tws0_rot"), transform.getTransform(self.legBones[0])) self.tws0_rot.setAttr("sx", .001) self.tws1_loc = primitive.addTransform( self.mid1_jnt, self.getName("tws1_loc"), transform.getTransform(self.mid1_jnt)) self.tws1_rot = primitive.addTransform( self.tws1_loc, self.getName("tws1_rot"), transform.getTransform(self.mid1_jnt)) self.tws1_rot.setAttr("sx", .001) self.tws2_loc = primitive.addTransform( self.mid2_jnt, self.getName("tws2_loc"), transform.getTransform(self.mid2_jnt)) self.tws2_rot = primitive.addTransform( self.tws2_loc, self.getName("tws2_rot"), transform.getTransform(self.mid2_jnt)) self.tws2_rot.setAttr("sx", .001) self.tws3_loc = primitive.addTransform( self.legBones[3], self.getName("tws3_loc"), transform.getTransform(self.legBones[3])) self.tws3_rot = primitive.addTransform( self.tws3_loc, self.getName("tws3_rot"), transform.getTransform(self.legBones[3])) self.tws3_rot.setAttr("sx", .001) # Divisions ---------------------------------------- # We have at least one division at the start, the end and one for # the knee and one ankle o_set = self.settings self.divisions = o_set["div0"] + o_set["div1"] + o_set["div2"] + 4 self.div_cns = [] for i in range(self.divisions): div_cns = primitive.addTransform(self.root_ctl, self.getName("div%s_loc" % i)) self.div_cns.append(div_cns) self.jnt_pos.append([div_cns, i]) # End reference ------------------------------------ # To help the deformation on the foot self.end_ref = primitive.addTransform( self.tws3_rot, self.getName("end_ref"), transform.getTransform(self.legBones[3])) self.jnt_pos.append([self.end_ref, 'end'])
def characterizeBiped(*args): try: gCtl = pm.PyNode('global_C0_ctl') mocapAttach = att.addAttribute(gCtl, "mocapAttach", "float", 1.0, minValue=0.0, maxValue=1.0) except: pm.displayWarning("global_C0_ctl: Is not in the scene") return # Align skeleton for a, b in zip(skelFK, gearFK): try: oA = pm.PyNode(a) except: pm.displayWarning(a + ": Is not in the scene") try: oB = pm.PyNode(b) except: pm.displayWarning(b + ": Is not in the scene") tra.matchWorldTransform(oB, oA) #constrain FK controls for a, b in zip(skelFK, gearFK): oA = pm.PyNode(a) oB = pm.PyNode(b) cns = pm.parentConstraint(oA, oB, mo=True) pb_node = pm.createNode("pairBlend") pm.connectAttr(cns + ".constraintRotateX", pb_node + ".inRotateX2") pm.connectAttr(cns + ".constraintRotateY", pb_node + ".inRotateY2") pm.connectAttr(cns + ".constraintRotateZ", pb_node + ".inRotateZ2") pm.connectAttr(pb_node + ".outRotateX", oB + ".rotateX", f=True) pm.connectAttr(pb_node + ".outRotateY", oB + ".rotateY", f=True) pm.connectAttr(pb_node + ".outRotateZ", oB + ".rotateZ", f=True) pm.setKeyframe(oB, at="rotateX") pm.setKeyframe(oB, at="rotateY") pm.setKeyframe(oB, at="rotateZ") pm.connectAttr(cns + ".constraintTranslateX", pb_node + ".inTranslateX2") pm.connectAttr(cns + ".constraintTranslateY", pb_node + ".inTranslateY2") pm.connectAttr(cns + ".constraintTranslateZ", pb_node + ".inTranslateZ2") pm.connectAttr(pb_node + ".outTranslateX", oB + ".translateX", f=True) pm.connectAttr(pb_node + ".outTranslateY", oB + ".translateY", f=True) pm.connectAttr(pb_node + ".outTranslateZ", oB + ".translateZ", f=True) pm.setKeyframe(oB, at="translateX") pm.setKeyframe(oB, at="translateY") pm.setKeyframe(oB, at="translateZ") pm.connectAttr(mocapAttach, pb_node.attr("weight")) #align IK controls with FK controls for a, b in zip(alignIK, alignFK): oA = pm.PyNode(a) oB = pm.PyNode(b) tra.matchWorldTransform(oB, oA) if a in [u'arm_L0_upv_ctl', u'arm_R0_upv_ctl']: oA.attr("tz").set(-3) if a == u'arm_L0_ikcns_ctl': oA.attr("rx").set((oA.attr("rx").get() + 90)) if a == u'arm_R0_ikcns_ctl': oA.attr("rx").set((oA.attr("rx").get() - 90)) # constrain IK controls for a, b in zip(skelIK, gearIK): oA = pm.PyNode(a) oB = pm.PyNode(b) print b pb_node = pm.createNode("pairBlend") try: if b in [u'leg_L0_upv_ctl', u'leg_R0_upv_ctl']: att.lockAttribute(pm.PyNode(b), lock=False, keyable=True) if b in [ u'leg_L0_mid_ctl', u'leg_R0_mid_ctl', u'arm_L0_mid_ctl', u'arm_R0_mid_ctl' ]: cns = pm.pointConstraint(oA, oB, mo=True) else: cns = pm.parentConstraint(oA, oB, mo=True) pm.connectAttr(cns + ".constraintRotateX", pb_node + ".inRotateX2") pm.connectAttr(cns + ".constraintRotateY", pb_node + ".inRotateY2") pm.connectAttr(cns + ".constraintRotateZ", pb_node + ".inRotateZ2") pm.connectAttr(pb_node + ".outRotateX", oB + ".rotateX", f=True) pm.connectAttr(pb_node + ".outRotateY", oB + ".rotateY", f=True) pm.connectAttr(pb_node + ".outRotateZ", oB + ".rotateZ", f=True) pm.setKeyframe(oB, at="rotateX") pm.setKeyframe(oB, at="rotateY") pm.setKeyframe(oB, at="rotateZ") except: cns = pm.pointConstraint(oA, oB, mo=True) pm.connectAttr(cns + ".constraintTranslateX", pb_node + ".inTranslateX2") pm.connectAttr(cns + ".constraintTranslateY", pb_node + ".inTranslateY2") pm.connectAttr(cns + ".constraintTranslateZ", pb_node + ".inTranslateZ2") pm.connectAttr(pb_node + ".outTranslateX", oB + ".translateX", f=True) pm.connectAttr(pb_node + ".outTranslateY", oB + ".translateY", f=True) pm.connectAttr(pb_node + ".outTranslateZ", oB + ".translateZ", f=True) pm.setKeyframe(oB, at="translateX") pm.setKeyframe(oB, at="translateY") pm.setKeyframe(oB, at="translateZ") pm.connectAttr(mocapAttach, pb_node.attr("weight"))
def addJoint(self, obj, name, newActiveJnt=None, UniScale=False, segComp=0, gearMulMatrix=True): """Add joint as child of the active joint or under driver object. Args: obj (dagNode): The input driver object for the joint. name (str): The joint name. newActiveJnt (bool or dagNode): If a joint is pass, this joint will be the active joint and parent of the newly created joint. UniScale (bool): Connects the joint scale with the Z axis for a unifor scalin, if set Falsewill connect with each axis separated. segComp (bool): Set True or False the segment compensation in the joint.. gearMulMatrix (bool): Use the custom gear_multiply matrix node, if False will use Maya's default mulMatrix node. Returns: dagNode: The newly created joint. """ if self.options["joint_rig"]: if newActiveJnt: self.active_jnt = newActiveJnt jnt = primitive.addJoint(self.active_jnt, self.getName(str(name) + "_jnt"), transform.getTransform(obj)) # TODO: Set the joint to have always positive scaling # jnt.scale.set([1, 1, 1]) # Disconnect inversScale for better preformance if isinstance(self.active_jnt, pm.nodetypes.Joint): try: pm.disconnectAttr(self.active_jnt.scale, jnt.inverseScale) except RuntimeError: # This handle the situation where we have in between joints # transformation due a negative scaling pm.ungroup(jnt.getParent()) # All new jnts are the active by default self.active_jnt = jnt if gearMulMatrix: mulmat_node = applyop.gear_mulmatrix_op( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output") m = mulmat_node.attr('output').get() else: mulmat_node = node.createMultMatrixNode( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode(mulmat_node + ".matrixSum") m = mulmat_node.attr('matrixSum').get() pm.connectAttr(dm_node + ".outputTranslate", jnt + ".t") pm.connectAttr(dm_node + ".outputRotate", jnt + ".r") # TODO: fix squash stretch solver to scale the joint uniform # the next line cheat the uniform scaling only fo X or Y axis # oriented joints if UniScale: pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sx") pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sy") pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sz") else: pm.connectAttr(dm_node + ".outputScale", jnt + ".s") pm.connectAttr(dm_node + ".outputShear", jnt + ".shear") # Segment scale compensate Off to avoid issues with the global # scale jnt.setAttr("segmentScaleCompensate", segComp) jnt.setAttr("jointOrient", 0, 0, 0) # setting the joint orient compensation in order to have clean # rotation channels jnt.attr("jointOrientX").set(jnt.attr("rx").get()) jnt.attr("jointOrientY").set(jnt.attr("ry").get()) jnt.attr("jointOrientZ").set(jnt.attr("rz").get()) im = m.inverse() if gearMulMatrix: mul_nod = applyop.gear_mulmatrix_op(mulmat_node.attr('output'), im, jnt, 'r') dm_node2 = mul_nod.output.listConnections()[0] else: mul_nod = node.createMultMatrixNode( mulmat_node.attr('matrixSum'), im, jnt, 'r') dm_node2 = mul_nod.matrixSum.listConnections()[0] if jnt.attr("sz").get() < 0: # if negative scaling we have to negate some axis for rotation neg_rot_node = pm.createNode("multiplyDivide") pm.setAttr(neg_rot_node + ".operation", 1) pm.connectAttr(dm_node2.outputRotate, neg_rot_node + ".input1", f=True) for v, axis in zip([-1, -1, 1], "XYZ"): pm.setAttr(neg_rot_node + ".input2" + axis, v) pm.connectAttr(neg_rot_node + ".output", jnt + ".r", f=True) # set not keyable attribute.setNotKeyableAttributes(jnt) else: jnt = primitive.addJoint(obj, self.getName(str(name) + "_jnt"), transform.getTransform(obj)) pm.connectAttr(self.rig.jntVis_att, jnt.attr("visibility")) attribute.lockAttribute(jnt) self.addToGroup(jnt, "deformers") # This is a workaround due the evaluation problem with compound attr # TODO: This workaround, should be removed onces the evaluation issue # is fixed # github issue: Shifter: Joint connection: Maya evaluation Bug #210 dm = jnt.r.listConnections(p=True, type="decomposeMatrix") if dm: at = dm[0] dm_node = at.node() pm.disconnectAttr(at, jnt.r) pm.connectAttr(dm_node.outputRotateX, jnt.rx) pm.connectAttr(dm_node.outputRotateY, jnt.ry) pm.connectAttr(dm_node.outputRotateZ, jnt.rz) dm = jnt.t.listConnections(p=True, type="decomposeMatrix") if dm: at = dm[0] dm_node = at.node() pm.disconnectAttr(at, jnt.t) pm.connectAttr(dm_node.outputTranslateX, jnt.tx) pm.connectAttr(dm_node.outputTranslateY, jnt.ty) pm.connectAttr(dm_node.outputTranslateZ, jnt.tz) dm = jnt.s.listConnections(p=True, type="decomposeMatrix") if dm: at = dm[0] dm_node = at.node() pm.disconnectAttr(at, jnt.s) pm.connectAttr(dm_node.outputScaleX, jnt.sx) pm.connectAttr(dm_node.outputScaleY, jnt.sy) pm.connectAttr(dm_node.outputScaleZ, jnt.sz) return jnt
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 o_node = applyop.gear_inverseRotorder_op(bk_ctl, fk_ctl) pm.connectAttr(o_node + ".output", bk_loc.attr("ro")) pm.connectAttr(fk_ctl.attr("ro"), fk_loc.attr("ro")) attribute.lockAttribute(bk_ctl, "ro") # Compensate the backward rotation # ik addx_node = node.createAddNode( bk_ctl.attr("rx"), bk_loc.attr("rx")) addy_node = node.createAddNode( bk_ctl.attr("ry"), bk_loc.attr("ry")) addz_node = node.createAddNode( bk_ctl.attr("rz"), bk_loc.attr("rz")) addz_node = node.createAddNode( addz_node + ".output", -bk_loc.getAttr("rz") - fk_loc.getAttr("rz")) neg_node = node.createMulNode([addx_node + ".output", addy_node + ".output", 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