class LegSystemGuide(SystemGuide): markerNames = ("Root", "Knee", "Ankle", "Eff") markerPositions = dict( Root=Vector3([15, 100, 0]), Knee=Vector3([15, 50, 5]), Ankle=Vector3([15, 10, 0]), Eff=Vector3([15, 10, 5]), ) markerPicked = ("Root", "Knee", "Wrist", "Eff") markerCurves = dict(DispCrv=("Root", "Knee", "Wrist", "Eff")) def addSettings(self): self._settings["blend"] = "IK" # FK, IK self._settings["lockKneeRotation"] = False self._settings["stretchDefault"] = 1.5 self._settings["reverseDefault"] = 0.0 self._settings["ankleUpVector"] = "World Y" # World Y, Guide Z def connectionPorts(self): super(LegSystemGuide, self).connectionPorts() ports = dict( Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], FK=["multiOrient"], IK=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UpVector=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UI=["uiHost"], ) return ports def connectionSlots(self): super(LegSystemGuide, self).connectionSlots() slots = dict( TwUprStart=(config.USE_RIG, "TwUprStart"), InterUpr=(config.USE_RIG, "InterUpr"), TwUprEnd=(config.USE_RIG, "TwUprEnd"), TwLwrStart=(config.USE_RIG, "TwLwrStart"), InterLwr=(config.USE_RIG, "InterLwr"), TwLwrEnd=(config.USE_RIG, "TwLwrEnd"), Foot=(config.USE_RIG, "Bone3"), Center=(config.USE_CTL, "Center"), IK=(config.USE_CTL, "Ik"), ) return slots
class DrivenSystemGuide(SystemGuide): markerNames = ("Rail", "Pos", "Neg") markerMinMax = dict(Rail=(1, -1), Pos=(1, -1), Neg=(1, -1)) markerPositions = dict( Rail1=Vector3([0, 5, 0]), Pos1=Vector3([0, 5, 2]), Neg1=Vector3([0, 5, -2]), ) markerPicked = ("Rail", ) def createMarkerCurves(self): for i in xrange(1, self.count("Rail") + 1): markers = [ self._markers["{}{}".format(x, i)].name() for x in ["Pos", "Rail", "Neg"] ] curve = create.cnsCurve(self.getMarkerName("DispCrv{}".format(i)), markers, degree=1) cmds.setAttr(curve + ".template", True) def addSettings(self): self._settings["addControllers"] = True self._settings["useIkColor"] = False self._settings["addControllers"] = False self._settings["addDeformerRef"] = False for i in xrange(1, self.count("Rail") + 1): self._settings["minRot%s" % i] = -90 self._settings["maxRot%s" % i] = 90 self._settings["axis%s" % i] = "Z" def connectionPorts(self): super(DrivenSystemGuide, self).connectionPorts() ports = {} for i in xrange(1, self.count("Rail") + 1): self.port["Rail{}".format(i)] = [ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ] self.port["Tracker"] = ["rotationTracker"] return ports def connectionSlots(self): super(DrivenSystemGuide, self).connectionSlots() use = config.USE_CTL if self._settings( "addControllers") else config.USE_RIG slots = dict() for i in xrange(1, self.count("Rail") + 1): slots["Part%s" % i] = (use, "Part%s" % i) return slots
class PsdSystemGuide(SystemGuide): markerNames = ("Root", "Driver", "Inner", "Outer") markerMinMax = dict(Driver=(1, -1), Inner=(1, -1), Outer=(1, -1)) markerPositions = dict( Root=Vector3([0, 0, 0]), Driver1=Vector3([0, 0, 0]), Inner1=Vector3([-2, 0, 0]), Outer1=Vector3([2, 0, 0]), ) markerPicked = ( "Root", "Driver", ) def createMarkerCurves(self): for i in xrange(1, self.count("Driver") + 1): markers = [ self._markers["{}{}".format(x, i)].name() for x in ["Inner", "Driver", "Outer"] ] curve = create.cnsCurve(self.getMarkerName("DispCrv{}".format(i)), markers, degree=1) cmds.setAttr(curve + ".template", True) def addSettings(self): for i in xrange(1, self.count("Driver") + 1): self._settings["drvName{}".format(i)] = "Driver{}".format(i) self._settings["interpType{}".format(i)] = "Linear" self._settings["twistAxis"] = "X" self._settings["twistInterp"] = "Linear" self._settings["twistMin"] = -90 self._settings["twistMax"] = 90 self._settings["twistSplit"] = True def connectionPorts(self): super(PsdSystemGuide, self).connectionPorts() ports = dict(Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], Tracker=["rotationTracker"], Orient=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ]) return ports def connectionSlots(self): super(PsdSystemGuide, self).connectionSlots() slots = dict(Root=(config.USE_RIG, "Root")) return slots
def _convertTransformToMatrix(translation, rotation, scaling): rotation = rotation[1:] + rotation[:1] translation = Vector3(translation) rotation = Quaternion(rotation) scaling = Vector3(scaling) transform = Transformation.fromParts(translation, rotation, scaling) return transform.asMatrix().flattened()
class ArmSystemGuide(SystemGuide): markerNames = ("Root", "Elbow", "Wrist", "Eff", "Prop") markerPositions = dict( Root=Vector3([17, 145, 0]), Elbow=Vector3([38, 125, 0]), Wrist=Vector3([55, 110, 12]), Eff=Vector3([61, 98, 17]), Prop=Vector3([57, 100, 14]), ) markerPicked = ("Root", "Elbow", "Wrist", "Eff") markerCurves = dict(DispCrv=("Root", "Elbow", "Wrist", "Eff")) def addSettings(self): self._settings["blend"] = "FK" # FK, IK self._settings["lockElbowRotation"] = False self._settings["gimbalControllers"] = False self._settings["stretchDefault"] = 1.5 self._settings["reverseDefault"] = 0.0 def connectionPorts(self): super(ArmSystemGuide, self).connectionPorts() ports = dict( Root=["slotParent", "meshAttach", "multiParent", "customParent"], FK=["multiOrient"], IK=["slotParent", "meshAttach", "multiParent", "customParent"], UpVector=[ "slotParent", "meshAttach", "multiParent", "customParent" ], UI=["uiHost"], ) return ports def connectionSlots(self): super(ArmSystemGuide, self).connectionSlots() slots = dict( TwUprStart=(config.USE_RIG, "TwUprStart"), InterUpr=(config.USE_RIG, "InterUpr"), TwUprEnd=(config.USE_RIG, "TwUprEnd"), TwLwrStart=(config.USE_RIG, "TwLwrStart"), InterLwr=(config.USE_RIG, "InterLwr"), TwLwrEnd=(config.USE_RIG, "TwLwrEnd"), Hand=(config.USE_RIG, "Bone3"), Center=(config.USE_CTL, "Center"), Prop=(config.USE_CTL, "Prop"), IK=(config.USE_CTL, "Ik"), ) return slots
def createObjects(self): # TRANSFORMATION rootTfm = self.transforms("Root") rootTfm.scale = self.scales("Root") drvTfm = self.transforms("Driver") innerTfm = self.transforms("Inner") outerTfm = self.transforms("Outer") sample_pos = Vector3([1, 0, 0]) * rootTfm.asMatrix() sampleTfm = rootTfm.copy(translation=sample_pos) self._root = self.addRig(None, "Root", rootTfm, "sphere", 1.0) self._sample = self.addRig(None, "Sample", sampleTfm, "null", 0.25) # Drivers self._drvs = [] self._inners = [] self._outers = [] for i, (dtfm, itfm, otfm) in enumerate(izip(drvTfm, innerTfm, outerTfm), start=1): dtfm.scale = self.scales("Driver")[i - 1] itfm.scale = self.scales("Inner")[i - 1] otfm.scale = self.scales("Outer")[i - 1] driver = self.addRig(self._root, "Driver%s" % i, dtfm, "pyramid", 0.5, None, [0, 0, -90], None) outer = self.addRig(driver, "Outer%s" % i, otfm, "sphere", 2, None, None, [0, 1, 1]) inner = self.addRig(outer, "Inner%s" % i, itfm, "sphere", 2, None, None, [0, 1, 1]) self._drvs.append(driver) self._inners.append(inner) self._outers.append(outer)
class QuadrantSystemGuide(SystemGuide): markerNames = ("Root", ) markerPositions = dict(Root=Vector3([20, 0, 0]), ) markerPicked = ("Root", ) def addSettings(self): self._settings["north"] = True self._settings["south"] = True self._settings["east"] = True self._settings["west"] = True self._settings["push"] = 2.0 self._settings["customLabel"] = False self._settings["label"] = "Label" self._settings["labelPosition"] = "North" def connectionPorts(self): super(QuadrantSystemGuide, self).connectionPorts() ports = dict(Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ]) return ports def connectionSlots(self): super(QuadrantSystemGuide, self).connectionSlots() slots = dict(Ctl=(config.USE_CTL, "Root")) return slots
class CameraSystemGuide(SystemGuide): markerNames = ("Root",) markerPositions = dict( Root=Vector3([0,175,60]), ) markerPicked = ("Root",) def createMarkers(self, matrices): parent = self.model() matrix = matrices["Root"] if "Root" in matrices else None self.addMarkerCamera("Root", parent=None, matrix=matrix) def addSettings(self): # Camera settings (such as FOV) are directly taken from the marker attributes pass def connectionPorts(self): super(CameraSystemGuide, self).connectionPorts() ports = dict( Root=["slotParent", "meshAttach", "multiParent", "customParent"], ) return ports def connectionSlots(self): super(CameraSystemGuide, self).connectionSlots()
def exampleA(mirror=False, showWindow=False): '''Built a basic and a chain system. Set the basic to be dynamic and connect the chain to it. Args: mirror (bool): True to duplicate the systems on the right side showWindow (bool): True to popup Brigks Main Window ''' # Building Matrix for guide positions basicMatrices = dict( Part1=Transformation.fromParts(translation=Vector3([2, 2, 0])), Part2=Transformation.fromParts(translation=Vector3([4, 2, 0])), ) chainMatrices = dict( Part1=Transformation.fromParts(translation=Vector3([2, 3, 0])), Part2=Transformation.fromParts(translation=Vector3([4, 4, 0])), Part3=Transformation.fromParts(translation=Vector3([6, 3, 0])), ) # Create Guide, add a layer and a couple Systems guide = Guide() guide.setSettings(hideRig=False) guide.setSettings(hideJoints=False) layer = guide.addLayer("MyFirstLayer") basic = layer.addSystem("basic", "L", "Basic", basicMatrices) chain = layer.addSystem("chain", "L", "Chain", chainMatrices) # System Settings basic.setSettings(dynamic=True, dynamicAnimatable=True, strap=True) # Connections chain.addConnection("Root", "slotParent", key=basic.key(), slot="Part1") if mirror: for system in layer.systems().values(): system.duplicate(mirror=True) # Save edit guide.commit() # Build all rig guide.build() if showWindow: showWindow() return guide
class LookatSystemGuide(SystemGuide): markerNames = ("Root", "Eff", "Ctrl") markerPositions = dict( Root=Vector3([0, 10, 0]), Eff=Vector3([0, 10, 10]), Ctrl=Vector3([0, 15, 0]), ) markerPicked = ("Root", "Eff") markerCurves = dict(DispCrv=("Root", "Eff")) def addSettings(self): self._settings["addLocalController"] = True self._settings["addTargetController"] = True self._settings["addUpVController"] = False self._settings["extraOffsetController"] = False self._settings["keepRotationOffset"] = False def connectionPorts(self): super(LookatSystemGuide, self).connectionPorts() ports = dict(Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], Eff=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UpVector=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UI=["uiHost"]) return ports def connectionSlots(self): super(LookatSystemGuide, self).connectionSlots() slots = dict(Direction=(config.USE_RIG, "Direction"), Local=(config.USE_RIG, "Local")) if self._settings["extraOffsetController"]: slots["Offset"] = (config.USE_RIG, "Offset") return slots
class StretchSystemGuide(SystemGuide): markerNames = ("Root", "Eff") markerPositions = dict( Root=Vector3([20, 0, 0]), Eff=Vector3([20, 10, 0]), ) markerCompatibility = dict(piston={}, ) markerPicked = ("Root", "Eff") markerCurves = dict(DispCrv=("Root", "Eff")) def addSettings(self): self._settings["addControllers"] = False self._settings["twist"] = True self._settings["twistBlend"] = .5 self._settings["stretch"] = True self._settings["stretchBlend"] = 1.0 self._settings["squash"] = False self._settings["squashy"] = 1.0 self._settings["squashz"] = 1.0 def connectionPorts(self): super(StretchSystemGuide, self).connectionPorts() ports = dict(Start=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], End=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UI=("uiHost")) return ports def connectionSlots(self): super(StretchSystemGuide, self).connectionSlots() slots = dict(Bone=(config.USE_RIG, "Bone")) return slots
class NeckSystemGuide(SystemGuide): markerNames = ("Root", "Head", "Eff") markerPositions = dict( Root=Vector3([0, 155, 0]), Head=Vector3([0, 170, 3]), Eff=Vector3([0, 185, 3]), ) markerPicked = ("Root", "Head", "Eff") markerCurves = dict(DispCrv=("Root", "Head", "Eff")) def addSettings(self): self._settings["kinematic"] = "FK/IK" # IK or FK/IK self._settings["blend"] = "IK" # FK, IK self._settings["stretch"] = 0.0 self._settings["gimbalControllers"] = False self._settings["extraHeadController"] = False self._settings["orientToWorld"] = False def connectionPorts(self): super(NeckSystemGuide, self).connectionPorts() ports = dict(Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], IK=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], Orient=["multiOrient"], UI=("uiHost")) return ports def connectionSlots(self): super(NeckSystemGuide, self).connectionSlots() slots = {} for i, s in enumerate(["Root", "Mid", "Head"], start=1): slots[s] = (config.USE_RIG, "Hook{}".format(i)) return slots
def translation(self): if self._translation is None: translation = cmds.xform(self._marker, q=True, translation=True, worldSpace=True) self._translation = Vector3(translation) if self._mirrored: self._translation.x = -self._translation.x return self._translation
def _createTangentObjects(self, prefix, i, size, bone, btfm, dist, icon): pos = Vector3([dist,0,0]) * btfm.asMatrix() tfm = btfm.copy(translation=pos) tanBfr = self.addBfr(bone, "{s}{i}".format(s=prefix,i=i+1), tfm=tfm) tanSolve = self.addRig(tanBfr, "{s}Solve{i}".format(s=prefix,i=i+1), tfm=tfm) tanCtl = self.addCtl(tanSolve, "{s}{i}".format(s=prefix,i=i+1), tfm, icon, size=size * 0.5, color=self.colorIk()) attributes.setKeyables(tanCtl, ["posx","posy","posz"]) # self.addToSubControllers(tanCtl) return tanBfr, tanSolve, tanCtl
class PistonSystemGuide(SystemGuide): markerNames = ("Root", "Eff") markerPositions = dict( Root=Vector3([10, 0, 0]), Eff=Vector3([10, 10, 0]), ) markerCompatibility = dict(stretch={}, ) markerPicked = ("Root", "Eff") markerCurves = dict(DispCrv=("Root", "Eff")) def addSettings(self): self._settings["addControllers"] = False self._settings["interDeformers"] = 0 def connectionPorts(self): super(PistonSystemGuide, self).connectionPorts() ports = dict(Start=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], End=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UI=["uiHost"]) return ports def connectionSlots(self): super(PistonSystemGuide, self).connectionSlots() slots = dict(StretchStart=(config.USE_RIG, "StretchStart"), StretchEnd=(config.USE_RIG, "StretchEnd")) for i in xrange(1, self.settings("interDeformers") + 1): slots["Div{}".format(i)] = (config.USE_RIG, "Div{}".format(i)) return slots
class MetaSystemGuide(SystemGuide): markerNames = ("Part", "Eff") markerMinMax = dict(Part=(2, -1), Eff=(2, -1)) markerPositions = dict( Part1=Vector3([55, 105, 15]), Part2=Vector3([55, 105, 13]), Part3=Vector3([55, 105, 11]), Part4=Vector3([55, 105, 9]), Eff1=Vector3([60, 105, 15]), Eff2=Vector3([60, 105, 13]), Eff3=Vector3([60, 105, 11]), Eff4=Vector3([60, 105, 9]), ) markerPicked = ("Part", ) markerCurves = dict(DispCrv=("Part", )) def createMarkerCurves(self): for i in xrange(1, self.count("Part") + 1): markers = [ self._markers["{}{}".format(x, i)].name() for x in ["Part", "Eff"] ] self.addMarkerDispCurve("Crv{}".format(i), markers) def addSettings(self): self._settings["startController"] = True self._settings["interController"] = False def connectionPorts(self): super(MetaSystemGuide, self).connectionPorts() ports = dict(Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ]) return ports def connectionSlots(self): super(MetaSystemGuide, self).connectionSlots() slots = dict() for i in range(1, self.count("Part") + 1): slots["Bone{}".format(i)] = (config.USE_CTL, "Part{}".format(i)) return slots
def createObjects(self): # SIZE size = self.translations("Root").distance(self.translations("Eff")) # TRANSFORMATION # Normal normal = self.directions("Root", "z") direction = self.translations("Eff") - self.translations("Root") rootTfm = Transformation.lookAt(self.translations("Root"), direction, normal, self.nsign() + "yz", self.negate()) dynTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "xz", self.negate()) posTfm = dynTfm.copy(translation=self.translations("Eff")) upvPos = Vector3([0, 0, 10]) * dynTfm.asMatrix() # OBJECTS # Controller self.dynBfr = self.addBfr(None, "Part1", dynTfm) self.dynCtl = self.addCtl(self.dynBfr, "Part1", dynTfm, "sphere", size=size, po=(self.factor(), 0, 0), so=(1, 1, 0), color=self.colorFk()) attributes.setKeyables(self.dynCtl) # self.setInversedParameters(self.dynCtl, middle=["posz", "rotx", "roty"]) self.posBfr = self.addBfr(self.dynBfr, "Part2", posTfm) self.posCtl = self.addCtl(self.posBfr, "Part2", posTfm, "sphere", size=size * 1.5, so=[0, 1, 1], color=self.colorIk()) attributes.setKeyables(self.posCtl) # self.setInversedParameters(self.posCtl, middle=["posz", "rotx", "roty"]) # Dynamic ---------------------------- self.harmonic = self.addRig(self.posCtl, "Harmonic", posTfm, "diamond", size=1)
class BreastSystemGuide(SystemGuide): markerNames = ("Root", "Eff") markerPositions = dict( Root=Vector3([5, 135, 5]), Eff=Vector3([5, 135, 10]), ) markerPicked = ("Root", "Eff") markerCurves = dict(DispCrv=("Root", "Eff")) def addSettings(self): self._settings["dynActive"] = False self._settings["amplitude"] = 1.0 self._settings["amplitudeX"] = 0.0 self._settings["amplitudeY"] = 1.0 self._settings["amplitudeZ"] = 1.0 self._settings["decay"] = 8.0 self._settings["frequency"] = .25 self._settings["termination"] = 0.0 self._settings["dynamicAnimatable"] = False def connectionPorts(self): super(BreastSystemGuide, self).connectionPorts() ports = dict(Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UI=["uiHost"]) return ports def connectionSlots(self): return {}
def transform(self): if self._transform is None: self._matrix = cmds.xform(self._marker, q=True, matrix=True, worldSpace=True) self._transformWithScale = Matrix4(self._matrix).asTransform() if self._mirrored: self._transformWithScale = self._transformWithScale.mirrored() self._transform = copy(self._transformWithScale) self._transform.scale = Vector3([1, 1, 1]) self._translation = self._transform.translation self._scale = self._transform.scale return self._transform
class FootSystemGuide(SystemGuide): markerNames = ("Root", "Part", "Heel", "In", "Out") markerMinMax = dict( Part=(2,-1) ) markerPositions = dict( Root=Vector3([15,10,0]), Part1=Vector3([15,5,10]), Part2=Vector3([15,2,20]), Heel=Vector3([15,0,-5]), In=Vector3([8,0,3]), Out=Vector3([22,0,3]), ) markerPicked = ("Root", "Part", "Heel") markerCurves = dict( DispCrv=("Root", "Part", "Heel"), SideCrv=("In", "Heel", "Out") ) def addSettings(self): for i in range(self.count("Part")): self._settings["angle%s"%(i+1)] = 20 self._settings["rollControl"] = "Slider" # Slider, Controller def connectionPorts(self): super(FootSystemGuide, self).connectionPorts() ports = dict( Root=["footLegAttach"], UI=["uiHost"] ) return ports def connectionSlots(self): super(FootSystemGuide, self).connectionSlots() slots = dict( Root=(config.USE_RIG, "FkRef") ) for i in xrange(1, self.count("Part")): slots["Bone%s"%i] = (config.USE_CTL, "Fk%s"%i) return slots
class AverageSystemGuide(SystemGuide): markerNames = ("Root",) markerPositions = dict( Root=Vector3([0,10,0]), ) markerPicked = ("Root",) def addSettings(self): self._settings["addControllers"] = False self._settings["blendAnimatable"] = False self._settings["blend"] = .5 self._settings["position"] = True self._settings["rotation"] = True self._settings["scaling"] = True def connectionPorts(self): super(AverageSystemGuide, self).connectionPorts() ports = dict( Average=["averageTransform"], UI=["uiHost"] ) return ports def connectionSlots(self): super(AverageSystemGuide, self).connectionSlots() use = config.USE_CTL if self.settings("addControllers") else config.USE_BFR slots = dict( Average=(use, "Average") ) return slots
def createObjects(self): # Search for optional Upv marker to determine normal if "Upv" in self.translations(): upv_pos = self.translations("Upv") normal = self.translations("Upv") - self.translations("Root") else: normal = self.directions("Root", "z") upv_pos = None # Transformation direction = self.translations("Eff") - self.translations("Root") dirTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "xz", self.negate()) ctlTfm = Transformation.lookAt(self.translations("Ctrl"), self.directions("Ctrl", "x"), self.directions("Ctrl", "z"), "xz", self.negate()) trgTfm = Transformation.lookAt(self.translations("Eff"), self.directions("Eff", "x"), self.directions("Eff", "z"), "xz", self.negate()) rigTfm = ctlTfm.copy(translation=self.translations("Root")) if self.settings("extraOffsetController") and self.settings( "keepRotationOffset"): offTfm = Transformation.lookAt(self.translations("Root"), self.directions("Root", "x"), self.directions("Root", "z"), "zy", self.negate()) offctlTfm = offTfm.copy(translation=self.translations("Ctrl")) else: offTfm = rigTfm offctlTfm = ctlTfm if not upv_pos: upv_pos = Vector3([0, 0, 10]) * dirTfm.asMatrix() upvTfm = dirTfm.copy(translation=upv_pos) # Direction self.dirRig = self.addRig(None, "Direction", dirTfm) # Up Vector upvBfr = self.addBfr(None, "Upv", upvTfm) if self.settings("addUpVController"): self.parentUpv = self.addCtl(upvBfr, "Upv", upvTfm, "diamond", size=.5, color=self.colorIk()) # self.addToSubControllers(self.parentUpv) else: self.parentUpv = upvBfr # Target self.targetBfr = self.addBfr(None, "Target", trgTfm) if self.settings("addTargetController"): # Target self.targetCtl = self.addCtl(self.targetBfr, "Target", trgTfm, "cube", size=1, color=self.colorIk()) # self.addToSubControllers(self.targetCtl) attributes.setKeyables(self.targetCtl, constants.ATTRS_T) # self.setInversedsettings(self.targetCtl, middle=["posy"]) if self.settings("addLocalController"): # Local Controller localBfr = self.addBfr(self.dirRig, "LocalNP", rigTfm) self.localRig = self.addRig(localBfr, "Local", rigTfm, "cube") # self.setNeutralPose(self.localRig) localBfr = self.addBfr(None, "Local", ctlTfm) self.localCtl = self.addCtl(localBfr, "Local", ctlTfm, "sphere", size=1, color=self.colorFk()) # self.setInversedsettings(self.localCtl, middle=["posx", "roty", "rotz"]) # Extra Offset Controller if self.settings("extraOffsetController"): self.offsetRig = self.addRig(self.localRig, "Offset", offTfm, "cube", size=.5) self.offsetCtl = self.addCtl(self.localCtl, "Offset", offctlTfm, "sphere", size=.5, color=self.colorIk())
def createObjects(self): # TRANSFORMATIONS positions = Vector3Array([ self.translations("Root"), self.translations("Knee"), self.translations("Ankle"), self.translations("Toe") ]) normal = Vector3.planeNormal(*positions[:3]) oriNormal = normal.copy() if self.negate(): normal *= -1 d = [(positions[i], positions[i + 1]) for i in range(3)] self.lengths = [Vector3.distance(a, b) for a, b in d] self.lengths.append(1) ratio = self.lengths[0] / sum(self.lengths[:2]) self.setSettings(lengths=self.lengths[:3]) # root rootTfm = Transformation.fromParts( translation=self.translations("Root")) # fk fkTfm = TransformationArray.chain(positions, normal, axis="xz", negativeSide=self.negate(), endTransform=False) lookAtEff = self.translations("Eff") - self.translations("Toe") fk3Tfm = Transformation.lookAt(self.translations("Toe"), lookAtEff, constants.AXIS_Y, "y-x", self.negate()) fkTfm = fkTfm.appended(fk3Tfm) for tfm, dist in izip(fkTfm, self.lengths): tfm.scale = Vector3( [dist * self.factor(), self.factor(), self.factor()]) bfrTfm = [ tfm.copy(rotation=fkTfm[max(i - 1, 0)].rotation) for i, tfm in enumerate(fkTfm) ] bfrTfm[0] = Transformation.lookAt(self.translations("Root"), constants.AXIS_NY, constants.AXIS_X, "x" + self.nsign() + "z", self.negate()) scale = bfrTfm[0].scale scale.x *= self.lengths[0] bfrTfm[0].scale = scale # ik ikbfrPos = Vector3([ self.translations("Root").x, self.translations("Toe").y, self.translations("Root").z ]) ikbfrTfm = Transformation.fromParts(translation=ikbfrPos) ikTfm = Transformation.lookAt(self.translations("Toe"), lookAtEff, constants.AXIS_Y, "zy", False) upvbfrTfm = Transformation.fromParts( translation=umath.upVector(self.translations("Root"), ikbfrPos, constants.AXIS_NX, ratio, False)) upvTfm = Transformation.fromParts( translation=umath.upVector(self.translations( "Root"), self.translations("Ankle"), oriNormal, ratio)) rollNormal = Vector3.planeNormal(self.translations("Root"), upvTfm.translation, self.translations("Toe")) if self.negate(): rollNormal *= -1 direction = self.translations("Root") - self.translations("Toe") rollbfrTfm = Transformation.lookAt(self.translations("Toe"), direction, rollNormal, "y-x", self.negate()) direction = self.translations("Ankle") - self.translations("Toe") rollTfm = Transformation.lookAt(self.translations("Toe"), direction, normal, "y-x", self.negate()) # extras scale = Vector3([self.factor(), self.factor(), self.factor()]) twisterTfm = {} interTfm = {} for i, (p, pos) in enumerate(izip(self.twp, positions[1:4])): twisterTfm[p] = [ fkTfm[i].copy(scale=scale), fkTfm[i].copy(translation=pos, scale=scale) ] interPos = twisterTfm[p][0].translation.lerp( twisterTfm[p][1].translation, .5) interTfm[p] = twisterTfm[p][0].copy(translation=interPos) ctrATfm = twisterTfm["Mid"][0] ctrBTfm = twisterTfm["Lwr"][0] # CONTROLLERS # Root self.rootBfr = self.addBfr(None, "Root", rootTfm) self.rootCtl = self.addCtl(self.rootBfr, "Root", rootTfm, "sphere", size=4, color=self.colorIk()) # self.addToSubControllers(self.rootCtl) attributes.setKeyables(self.rootCtl, constants.ATTRS_T) # self.setInversedParameters(self.rootCtl, middle=["posx"], side=["posx"]) # Fk Ref # Used as a reference for the upr start twist # We cannot use the fk1Bfr cause this one get constrained when fk ref changes self.fkRef = self.addRig(self.rootBfr, "FkRef", bfrTfm[0]) # FK Controlers and Bones fkParent = self.fkRef boneParent = self.fkRef self.fkBfr = [] self.fkCtl = [] self.bones = [] self.stretches = [] for i, (tfm, btfm) in enumerate(izip(fkTfm, bfrTfm), start=1): bfr = self.addBfr(fkParent, "Fk%s" % i, btfm) ctl = self.addCtl(bfr, "Fk%s" % i, tfm, "sphere", size=8, so=[0, 1, 1], color=self.colorFk()) if self.settings("lockKneeRotation") and i == 2: keyables = [ "posx", "posy", "posz", "rotz", "sclx", "scly", "sclz" ] else: keyables = constants.ATTRS_TRS if i == 1: attributes.setRotOrder(ctl, "XZY") attributes.setKeyables(ctl, keyables) # self.setInversedParameters(ctl, middle=["posz", "roty", "rotx"]) fkParent = ctl self.fkBfr.append(bfr) self.fkCtl.append(ctl) bone = self.addRig(boneParent, "Bone{}".format(i), tfm=tfm, icon="bone", so=(self.factor(), 1, 1)) boneParent = bone self.bones.append(bone) # IK Controllers self.rollBfr = self.addBfr(self.rootBfr, "Roll", rollbfrTfm) self.rollCtl = self.addCtl(self.rollBfr, "Roll", rollTfm, "jaw", size=1, ro=(-90, 0, 0), color=self.colorIk()) #self.rollCtl = self.addCtl(self.rollBfr, "Roll", rollTfm, "jaw", size=2, po=(4,6,0), color=self.colorIk()) # self.setNeutralPose(self.rollCtl) attributes.setKeyables(self.rollCtl, ["rotx", "roty", "rotz", "rotorder", "scly"]) self.ikRef = self.addRig(self.rollCtl, "IkRef", fkTfm[-2]) self.ikBfr = self.addBfr(None, "Ik", ikbfrTfm) self.ikCtl = self.addCtl(self.ikBfr, "Ik", ikTfm, "cube", size=6, color=self.colorIk()) attributes.setKeyables(self.ikCtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ikCtl, middle=["posx", "rotz", "roty"], side=["posx", "rotz", "roty"]) attributes.setRotOrder(self.ikCtl, "XZY") self.ikoffCtl = self.addCtl(self.ikCtl, "IkOffset", ikTfm, "null", size=4, color=self.colorIk()) # self.addToSubControllers(self.ikoffCtl) attributes.setKeyables(self.ikoffCtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ikoffCtl, middle=["posx", "rotz", "roty"], side=["posx", "rotz", "roty"]) attributes.setRotOrder(self.ikoffCtl, "XZY") self.upvBfr = self.addBfr(None, "Upv", upvbfrTfm) self.upvCtl = self.addCtl(self.upvBfr, "Upv", upvTfm, "diamond", size=2, color=self.colorIk()) attributes.setKeyables(self.upvCtl, constants.ATTRS_T) # self.setInversedParameters(self.upvCtl, middle=["posx"], side=["posx"]) self.ctrABfr = self.addBfr(self.bones[0], "CenterA", ctrATfm) self.ctrACtl = self.addCtl(self.ctrABfr, "CenterA", ctrATfm, "sphere", size=5, color=self.colorIk()) # self.addToSubControllers(self.ctrACtl) attributes.setKeyables(self.ctrACtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ctrACtl, middle=["posz", "roty", "rotx"]) self.ctrBBfr = self.addBfr(self.bones[1], "CenterB", ctrBTfm) self.ctrBCtl = self.addCtl(self.ctrBBfr, "CenterB", ctrBTfm, "sphere", size=5, color=self.colorIk()) # self.addToSubControllers(self.ctrBCtl) attributes.setKeyables(self.ctrBCtl, constants.ATTRS_TRS) # self.setInversedParameters(self.ctrBCtl, middle=["posz", "roty", "rotx"]) self.upvCrv = create.cnsCurve( self.getObjectName(config.USE_RIG, "UpvCrv"), [self.upvCtl, self.ctrACtl]) cmds.setAttr(self.upvCrv + ".template", True) self.footRef = self.addRig(self.ikoffCtl, "FootRef", ikTfm) # Twisters self.twisters = defaultdict(list) for p in self.twp: for s, tfm, factor in izip(["Start", "End"], twisterTfm[p], [1, -1]): twister = self.addRig(self.rootBfr, "Tw" + p + s, tfm, "sphere", po=[factor, 0, 0], so=[2, 1, 1]) # self.setNeutralPose(twister) self.twisters[p].append(twister) # Inter self.inters = {} for p in self.twp: self.inters[p] = self.addRig(self.rootBfr, "Inter" + p, interTfm[p], "pyramid")
class BasicSystemGuide(SystemGuide): markerNames = ("Part", ) markerMinMax = dict(Part=(1, -1), ) markerPositions = dict(Part1=Vector3([3, 10, 0]), ) markerCompatibility = dict( chain={}, tentacle={}, #chain=dict(Part="Bone"), # This is how it should be formated if you had to rename markers ) markerPicked = ("Part", ) def addSettings(self): self._settings["addControllers"] = True self._settings["useIkColor"] = False self._settings["addJointReference"] = False self._settings["tx"] = True self._settings["ty"] = True self._settings["tz"] = True self._settings["rx"] = True self._settings["ry"] = True self._settings["rz"] = True self._settings["sx"] = True self._settings["sy"] = True self._settings["sz"] = True self._settings["rotorder"] = True self._settings["defaultRotationOrder"] = "XYZ" self._settings["splitRotation"] = False self._settings["dynamic"] = False self._settings["dynActive"] = False self._settings["amplitude"] = 1.0 self._settings["amplitudeX"] = 1.0 self._settings["amplitudeY"] = 1.0 self._settings["amplitudeZ"] = 1.0 self._settings["decay"] = 8.0 self._settings["frequency"] = .25 self._settings["termination"] = 0.0 self._settings["dynamicAnimatable"] = False def connectionPorts(self): super(BasicSystemGuide, self).connectionPorts() ports = {} for part in self.markers().keys(): # port = marker.split("_")[-1] ports[part] = [ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent", "averageTransform", "multiOrient" ] ports["UI"] = ["uiHost"] return ports def connectionSlots(self): super(BasicSystemGuide, self).connectionSlots() slots = {} for part in self.markers().keys(): slots[part] = (config.USE_CTL, part) return slots
class ChainSystemGuide(SystemGuide): markerNames = ("Part", ) markerMinMax = dict(Part=(2, -1)) markerPositions = dict( Part1=Vector3([5, 10, 0]), Part2=Vector3([10, 10, 0]), ) markerPicked = ("Part", ) markerCurves = dict(DispCrv=("Part", )) markerCompatibility = dict( basic={}, tentacle={}, # basic=dict(Bone="Part") ) def addSettings(self): self._settings["orientation"] = "Auto" # Auto, Guide self._settings["kinematic"] = "FK" # FK, IK or FK/IK self._settings["blend"] = "FK" self._settings["setNeutralPose"] = True self._settings["defaultRotationOrder"] = "XYZ" self._settings["strap"] = False self._settings["strapDeformers"] = 5 self._settings["dynamic"] = False self._settings["dynActive"] = False self._settings["amplitude"] = 1.0 self._settings["amplitudeX"] = 1.0 self._settings["amplitudeY"] = 1.0 self._settings["amplitudeZ"] = 1.0 self._settings["decay"] = 8.0 self._settings["frequency"] = .25 self._settings["termination"] = 0.0 self._settings["dynamicAnimatable"] = False def connectionPorts(self): super(ChainSystemGuide, self).connectionPorts() ports = dict( Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], FK=["multiOrient"], IK=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UpVector=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UI=["uiHost"], ) return ports def connectionSlots(self): super(ChainSystemGuide, self).connectionSlots() if self._settings["dynamic"]: use = config.USE_RIG name = "Dynamic{}" elif self._settings["kinematic"] == "FK/IK": use = config.USE_RIG name = "Part{}" elif self._settings["kinematic"] == "FK": use = config.USE_CTL name = "Fk{}" else: use = config.USE_RIG name = "Ik{02d}" slots = dict() for i in xrange(1, self.count("Part")): slots["Bone{}".format(i)] = (use, name.format(i)) return slots
class TentacleSystemGuide(SystemGuide): markerNames = ("Part", ) markerMinMax = dict(Part=(2, -1)) markerPositions = dict( Part1=Vector3([0, 0, 0]), Part2=Vector3([0, 0, -10]), ) markerCompatibility = dict( basic=dict(), chain=dict(), ) markerPicked = ("Part", ) markerCurves = dict(DispCrv=("Part", )) def addSettings(self): self._settings["kinematic"] = "FK" # FK, IK or FK/IK self._settings["blend"] = "FK" self._settings["setNeutralPose"] = True self._settings["defaultRotationOrder"] = "XYZ" self._settings["jointsCount"] = 20 self._settings["lowJointsCount"] = 10 self._settings["minimumLength"] = 0.0 self._settings["addRootCtrl"] = False self._settings["addRoll"] = True self._settings["extraControllers"] = 0 self._settings["extraControllerSpacing"] = 0.1 self._settings["dynamic"] = False self._settings["dynActive"] = False self._settings["amplitude"] = 1.0 self._settings["amplitudeX"] = 1.0 self._settings["amplitudeY"] = 1.0 self._settings["amplitudeZ"] = 1.0 self._settings["decay"] = 8.0 self._settings["frequency"] = .25 self._settings["termination"] = 0.0 self._settings["dynamicAnimatable"] = False def connectionPorts(self): super(TentacleSystemGuide, self).connectionPorts() ports = dict( Root=["slotParent", "meshAttach", "multiParent", "customParent"], Orient=["multiOrient"], IK=["slotParent", "meshAttach", "multiParent", "customParent"], UI=["uiHost"]) return ports def connectionSlots(self): super(TentacleSystemGuide, self).connectionSlots() if self.settings("dynamic"): use = config.USE_RIG name = "Dynamic-{}-Bone1" elif self.settings("kinematic") == "FK/IK": name = "Bone{}" use = config.USE_RIG elif self.settings("kinematic") == "FK": name = "Fk{}" use = config.USE_CTL else: name = "Ik-Bone{}" use = config.USE_RIG slots = {} for i in xrange(1, self.count("Part") + 1): slots["Bone{}".format(i)] = (use, name.format(i)) return slots
def createObjects(self): # Settings self.isFk = "FK" in self.settings("kinematic") self.isIk = "IK" in self.settings("kinematic") self.isFkIk = self.isFk and self.isIk self.isNotIk = self.isFk and not self.isIk self.isNotFk = not self.isFk and self.isIk size = self.translations("Part")[0].distance(self.translations("Part")[1]) * 0.25 # TRANSFORMATION # Normal if self.count("Part") > 2: normal = Vector3.planeNormal(*self.translations("Part")[:3]) direction = self.translations("Part")[-1] - self.translations("Part")[0] if normal.length() < 1E-6: normal = self.directions("Part1", "z") if self.negate(): normal *= -1 else: direction = self.directions("Part1", "x") normal = self.directions("Part1", "z") boneTfm = TransformationArray.chain(self.translations("Part"), normal, negativeSide=self.negate(), endTransform=False) d = [(self.translations("Part")[i],self.translations("Part")[i+1]) for i in range(self.count("Part")-1)] self.distances = [Vector3.distance(a,b) for a,b in d] endTfm = boneTfm[-1].copy(translation=self.translations("Part")[-1]) boneTfm = boneTfm.appended(endTfm) self.distances.append(0.0) # Create extra transforms on end points for i in xrange(self.settings("extraControllers")): extraPos = Vector(self.settings("extraControllerSpacing")*(i+1),0,0) * endTfm extraTfm = endTfm.copy(translation=extraPos) boneTfm = boneTfm.appended(extraTfm) self.distances.append(0.0) self.setSettings(count=len(self.distances), lengths=self.distances) self.initialCount = self.count("Part") if self.settings("setNeutralPose"): bfrTfm = boneTfm else: bfrTfm = [tfm.copy(rotation=boneTfm[max(i-1,0)].quaternion) for i, tfm in enumerate(boneTfm)] if self.settings("dynamic"): dynTfm = [] for i, posA in enumerate(self.translations()[:-1]): posB = self.translations()[i+1] dynTfm.append(Transform.LookingAt(posA, posB, normal, self.nsign()+"yz", self.negate())) self.normal = normal.copy() self.normal.normalize() self.direction = direction.copy() self.direction.normalize() # OBJECTS # Root rootBfr = self.addBfr(None, "Root", tfm=boneTfm[0]) if self.settings("addRootCtrl"): self._root = self.addCtl(rootBfr, "Root", boneTfm[0], "sphere", size=size*1.5, color=self.colorFk()) else: self._root = rootBfr # FK Controllers ----------------------------------------- if self.isFk: self.fkBfr = [] self.fkCtl = [] parent = self._root for i, (tfm, btfm, dist) in enumerate(izip(boneTfm, bfrTfm, self.distances), start=1): if self.negate(): dist *= -1 fkBfr = self.addBfr(parent, "Fk{}".format(i), tfm=btfm) fkCtl = self.addCtl(fkBfr, "Fk{}".format(i), tfm, "cube", po=[dist*0.5,0,0], so=[dist*0.9,size,size], color=self.colorFk()) # self.setInversedsettings(fkCtl, middle=["posz", "rotx", "roty"]) attributes.setRotOrder(fkCtl, self.settings("defaultRotationOrder")) parent = fkCtl self.fkBfr.append(fkBfr) self.fkCtl.append(fkCtl) else: self.fkCtl = len(boneTfm) * [None] # IK Controllers -------------------------------------- if self.isIk: self.ikBfr = [] self.ikCtl = [] self.ikRoot = self.addBfr(self._root, "IkRoot", boneTfm[0]) for i, (tfm, btfm) in enumerate(izip(boneTfm, bfrTfm), start=1): if i == 1: parent = self._root else: parent = self.ikRoot ikBfr = self.addBfr(parent, "Ik{}".format(i), tfm=btfm) ikCtl = self.addCtl(ikBfr, "Ik{}".format(i), tfm, "sphere", size=size, color=self.colorIk()) # self.setInversedsettings(ikCtl, middle=["posz","rotx","roty"]) attributes.setRotOrder(ikCtl, self.settings("defaultRotationOrder")) self.ikBfr.append(ikBfr) self.ikCtl.append(ikCtl) else: self.ikCtl = len(boneTfm) * [None] # Bones ------------------------------- if self.isFkIk or (self.isFk and self.settings("dynamic")): self.bones = [] parent = self._root for i, (tfm, dist) in enumerate(izip(boneTfm, self.distances), start=1): if self.negate(): dist *= -1 bone = self.addRig(parent, "Bone{}".format(i), tfm, "cube", size=1, po=[dist*.5,0,0], so=[0,.5 * size,.5 * size]) self.bones.append(bone) parent = bone elif self.isFk: self.bones = self.fkCtl else: self.bones = self.ikCtl # Dynamic ---------------------------- if self.settings("dynamic"): self.dfmHost = [] self.dynCns = [] self.target = [] self.harmonic = [] self.dynBone = [] parent = self._root for i, (bone, tfmA, tfmB) in enumerate(izip(self.bones[:-1], boneTfm[:-1], boneTfm[1:]), start=1): dynCns = self.addRig(parent, "DynCns{}".format(i), tfmA, "cube", size=1) self.dynCns.append(dynCns) target = self.addRig(dynCns, "Target{}".format(i), tfmB, "null", size=1) self.target.append(target) harmonic = self.addRig(target, "Harmonic{}".format(i), tfmB, "diamond", size=1) self.harmonic.append(harmonic) dynBone = self.addRig(parent, "Dynamic{}".format(i), tfmA, "pyramid", size=1, ro=[0,0,-90], so=[1,self.factor(),1]) self.dynBone.append(dynBone) parent = dynBone self.dfmHost.append(dynBone) # Add the tip, since the tentacle has the tip dynBone = self.addRig(parent, "Dynamic{}".format(len(self.bones)), boneTfm[-1], "pyramid", size=1, ro=[0,0,-90], so=[1,self.factor(),1]) self.dynBone.append(dynBone) self.dfmHost.append(dynBone) else: self.dfmHost = self.bones # Roll Controllers ---------------------------- self.rollBfr = [] self.rollCtl = [] # self.upv = [] if self.settings("addRoll"): for i, (bone, tfm) in enumerate(izip(self.dfmHost, boneTfm), start=1): if self.negate(): rollScl = -2 else: rollScl = 2 rollBfr = self.addBfr(bone, "Roll{}".format(i), tfm=tfm) rollCtl = self.addCtl(rollBfr, "Roll{}".format(i), tfm, "pyramid", size=size, so=[1,rollScl,0], color=self.colorIk()) # self.setInversedsettings(rollCtl, middle=["posz","rotx","roty"]) attributes.setRotOrder(rollCtl, self.settings("defaultRotationOrder")) attributes.setKeyables(rollCtl, ["rotx"]) # self.addToSubControllers(rollCtl) upvPar = rollCtl self.rollBfr.append(rollBfr) self.rollCtl.append(rollCtl) # UI Hosts ---------------------------- self.hosts = [] for i, (bone, btfm) in enumerate(izip(self.dfmHost, boneTfm), start=1): host = self.addCtl(bone, "Host{}".format(i), btfm, "gear", size=size*1.5, color=self.colorFk()) attributes.setKeyables(host, []) self.hosts.append(host) # Tangents ---------------------------- self.tangentBfr = [] self.tangentSolvers = [] self.tangentCtl = [] self.tanCrvs = [] points = [] for i, (bone, btfm, dist) in enumerate(izip(self.dfmHost, boneTfm, self.distances)): tanBfrs = [] tanSolvers = [] tanCtls = [] if i: tangent = self._createTangentObjects("InTangent", i, size, bone, btfm, -self.distances[i-1]*0.333, "cube") tanBfrs.append(tangent[0]) tanSolvers.append(tangent[1]) tanCtls.append(tangent[2]) else: tanBfrs.append(None) tanSolvers.append(None) tanCtls.append(None) if i != len(self.bones)-1: tangent = self._createTangentObjects("OutTangent", i, size, bone, btfm, dist*0.333, "diamond") tanBfrs.append(tangent[0]) tanSolvers.append(tangent[1]) tanCtls.append(tangent[2]) else: tanBfrs.append(None) tanSolvers.append(None) tanCtls.append(None) self.tangentBfr.append(tanBfrs) self.tangentSolvers.append(tanSolvers) self.tangentCtl.append(tanCtls) # Draw helper lines for the tangents. Start by filtering out empty entries from the centers list centers = [item for item in [tanCtls[0], bone, tanCtls[1]] if item] tanCrv = create.cnsCurve("TanCrv{}".format(i+1), centers, degree=1) cmds.setAttr(tanCrv+".template", True) self.tanCrvs.append(tanCrv) # Curve ---------------------------- self.curvePar = self.addRig(None, "Curve") cmds.setAttr(self.curvePar+".template", True)
def createObjects(self): # TRANSFORMATIONS normal = Vector3.planeNormal(self.translations("Root"), self.translations("Part")[-1], self.translations("Heel")) if self.negate(): normal *= -1 rootTfm = Transformation.lookAt(self.translations("Root"), constants.AXIS_Y, normal, "y-x", self.negate()) direction = self.translations("Part")[-1] - self.translations("Heel") heelTfm = Transformation.lookAt(self.translations("Heel"), direction, normal, "xz", self.negate()) if self.count("Part") > 1: B = self.translations("Heel") - self.translations("Part")[-1] C = self.translations("Part")[0] - self.translations("Part")[-1] a = 1 - ((math.cos(B.angle(C)) * C.length()) / B.length()) else: a = .5 swivel_pos = self.translations("Heel").lerp( self.translations("Part")[-1], a) swivelTfm = heelTfm.copy(translation=swivel_pos) direction = self.translations("Part")[0] - self.translations("Root") fkrefTfm = Transformation.lookAt(self.translations("Root"), direction, normal, "xz", self.negate()) fkTfm = TransformationArray.chain(self.translations("Part"), normal, axis="xz", negativeSide=self.negate(), endTransform=False) fkTfm = fkTfm.appended( heelTfm.copy(translation=self.translations("Part")[-1])) # CONTROLLERS # Root self._root = self.addRig(None, "Root", rootTfm) # Heel self.heelBfr = self.addBfr(self._root, "Heel", heelTfm) self.heelRol = self.addRig(self.heelBfr, "HeelRoll", tfm=heelTfm) self.heelCtl = self.addCtl(self.heelRol, "Heel", heelTfm, "sphere", so=[1, 1, 0], color=self.colorIk()) attributes.setKeyables(self.heelCtl, constants.ATTRS_TR) # self.setInversedParameters(self.heelCtl, middle=["posz", "rotx", "roty"]) # Swivel self.swivelBfr = self.addBfr(self.heelCtl, "Swivel", swivelTfm) self.swivelCtl = self.addCtl(self.swivelBfr, "Swivel", swivelTfm, "sphere", so=[3, 0, 3], color=self.colorIk()) attributes.setKeyables(self.swivelCtl, constants.ATTRS_TR) # self.setInversedParameters(self.swivelCtl, middle=["posz", "rotx", "roty"]) # Roll self.rollCtl = self.addCtl(self._root, "Roll", rootTfm, "sphere", color=self.colorIk(), so=[0, 2, 2]) # self.addToSubControllers(self.rollCtl) attributes.setKeyables(self.rollCtl, ["rotx", "rotz"]) # self.setInversedParameters(self.rollCtl, middle=["rotz"]) # Backward Controllers parent = self.swivelCtl self.bkBfr = [] self.bkRol = [] self.bkCtl = [] for i, tfm in enumerate(reversed(fkTfm)): index = i + 1 bkBfr = self.addBfr(parent, "Bk%s" % index, tfm=tfm) bkRol = self.addRig(bkBfr, "Bk%sRoll" % index, tfm=tfm) bkCtl = self.addCtl(bkRol, "Bk%s" % index, tfm, "sphere", color=self.colorIk(), so=[1, 1, 0]) attributes.setKeyables(bkCtl, constants.ATTRS_R) # self.setInversedParameters(bkCtl, middle=["rotx", "roty"]) self.bkBfr.append(bkBfr) self.bkRol.append(bkRol) self.bkCtl.append(bkCtl) parent = bkCtl # Forward Controllers self.fkRef = self.addRig(self.bkCtl[-1], "FkRef", fkrefTfm) self.fkBfr = [] self.fkCtl = [] parent = self.fkRef for i, (tfm, bkCtl) in enumerate(izip(fkTfm, self.bkCtl[:-1]), start=1): fkBfr = self.addBfr(parent, "Fk%s" % i, tfm=tfm) fkCtl = self.addCtl(fkBfr, "Fk%s" % i, tfm, "sphere", color=self.colorFk(), so=[0, 2, 4]) attributes.setKeyables( fkCtl, [t + s for t, s in product(["scl", "rot", "pos"], "xyz")]) # self.setInversedParameters(fkCtl, middle=["posz", "rotx", "roty"]) parent = fkCtl self.fkBfr.append(fkBfr) self.fkCtl.append(fkCtl)
class SpineSystemGuide(SystemGuide): markerNames = ("Root", "Eff") markerPositions = dict( Root=Vector3([0, 100, 0]), Eff=Vector3([0, 135, 0]), ) markerPicked = ("Root", "Eff") markerCurves = dict(DispCrv=("Root", "Eff")) def createMarkers(self, matrices): super(SpineSystemGuide, self).createMarkers(matrices) # Auxiliaries to attach the twist spline aux25 = self.addMarker("Aux25", parent=self.markers("Root")) aux50 = self.addMarker("Aux50", parent=self.markers("Root")) aux75 = self.addMarker("Aux75", parent=self.markers("Root")) self.addCompound("twoPointsConstraint", "Aux25", aux25, self.markers("Root"), self.markers("Eff"), blend=.25, axis="x-z") self.addCompound("twoPointsConstraint", "Aux50", aux50, self.markers("Root"), self.markers("Eff"), blend=.50, axis="x-z") self.addCompound("twoPointsConstraint", "Aux75", aux75, self.markers("Root"), self.markers("Eff"), blend=.75, axis="x-z") for marker in [aux25, aux50, aux75]: cmds.setAttr(marker.name() + ".template", True) def addSettings(self): self._settings["blend"] = "IK" # FK, IK self._settings["breathing"] = False self._settings["axis"] = "YZ" def connectionPorts(self): super(SpineSystemGuide, self).connectionPorts() ports = dict(Root=[ "slotParent", "meshAttach", "nurbsParent", "multiParent", "customParent" ], UI=["uiHost"]) return ports def connectionSlots(self): super(SpineSystemGuide, self).connectionSlots() slots = dict(Pelvis=(config.USE_CTL, "Ik1"), Lower=(config.USE_RIG, "Hook2"), Middle=(config.USE_RIG, "Hook3"), Upper=(config.USE_RIG, "Hook4"), Chest=(config.USE_RIG, "Hook5"), Breathing=(config.USE_CTL, "Breathing")) return slots
def createObjects(self): # Settings self.isFk = "FK" in self.settings("kinematic") self.isIk = "IK" in self.settings("kinematic") self.isFkIk = self.isFk and self.isIk # TRANSFORMATION # Positions positions = self.translations("Part") # Normal if self.count("Part") > 2: normal = Vector3.planeNormal(*positions[:3]) if normal.length() < 1E-6: normal = self.directions("Part1", "z") if self.negate(): normal *= -1 else: normal = self.directions("Part1", "z") boneTfm = TransformationArray.chain(positions, normal, axis="xz", negativeSide=self.negate(), endTransform=False) d = [(positions[i], positions[i + 1]) for i in range(self.count("Part") - 1)] boneLen = [Vector3.distance(a, b) for a, b in d] self.setSettings(count=len(boneLen), lengths=boneLen) if self.settings("setNeutralPose"): bfrTfm = boneTfm else: bfrTfm = [ tfm.copy(rotation=boneTfm[max(i - 1, 0)].rotation) for i, tfm in enumerate(boneTfm) ] if self.isIk: ikTfm = boneTfm[-1].copy(translation=positions[-1]) # Up Vector if self.count("Part") > 2: upvTfm = Transformation.fromParts( translation=umath.upVector(positions[0], positions[2], normal, ratio=1, negate=self.negate())) else: upvTfm = Transformation.fromParts( translation=umath.upVector(positions[0], positions[1], normal, ratio=1, negate=self.negate())) if self.settings("dynamic"): tgtTfm = boneTfm[1:] tgtTfm = tgtTfm.appended( boneTfm[-1].copy(translation=positions[-1])) # OBJECTS # Root self._root = self.addRig(None, "Root", tfm=boneTfm[0]) # FK Controllers ----------------------------------------- if self.isFk: self.fkBfr = [] self.fkCtl = [] self.fkDir = [] parent = self._root for i, (tfm, btfm, dist) in enumerate(izip(boneTfm, bfrTfm, boneLen), start=1): fkBfr = self.addBfr(parent, "Fk{}".format(i), tfm=btfm) fkCtl = self.addCtl(fkBfr, "Fk{}".format(i), tfm, "sphere", so=[0, 1, 1], color=self.colorFk()) # self.setInversedsettings(fkCtl, middle=["posz", "rotx", "roty"]) attributes.setRotOrder(fkCtl, self.settings("defaultRotationOrder")) parent = fkCtl self.fkBfr.append(fkBfr) self.fkCtl.append(fkCtl) bone = self.addRig(fkCtl, "Dir{}".format(i), tfm, "pyramid", size=1, ro=[0, 0, -90], so=[.5, self.factor() * dist, .5]) self.fkDir.append(bone) # Add the end reference for ikfk matching tfm = boneTfm[-1].copy(translation=positions[-1]) self._tip = self.addRig(self.fkCtl[-1], "Tip", tfm) # IK Controllers -------------------------------------- if self.isIk: # Ik Controller self.ikBfr = self.addBfr(self._root, "Ik", tfm=ikTfm) self.ikCtl = self.addCtl(self.ikBfr, "Ik", ikTfm, "cube", size=2, color=self.colorIk()) attributes.setKeyables(self.ikCtl, constants.ATTRS_TR) # UpVector Controller self.upvBfr = self.addBfr(self._root, "UpV", upvTfm) self.upvCtl = self.addCtl(self.upvBfr, "UpV", upvTfm, "diamond", color=self.colorIk()) attributes.setKeyables(self.upvCtl, constants.ATTRS_T) # Ik Chain self.ikBones, self.effector, self.handle = create.chain( self.getObjectName(config.USE_RIG, "Ik"), self._root, positions, normal, negate=self.negate()) self.upvCrv = create.cnsCurve( [self.ikChn.root(), self.upvCtl, self.ikChn.effector()], "UpvCrv") cmds.setAttr(self.upvCrv + ".template", True) # Bones ------------------------------- if self.isFkIk: # or (self.isFk and self.settings("dynamic")): self.bones = [] parent = self._root for i, (tfm, dist) in enumerate(izip(boneTfm, boneLen), start=1): bone = self.addRig(parent, "Bone{}".format(i), tfm, "cube", size=1, po=[self.factor() * dist * .5, 0, 0], so=[dist, .5, .5]) self.bones.append(bone) parent = bone elif self.isFk: self.bones = self.fkCtl else: self.bones = self.ikChn.bones() # Dynamic ---------------------------- if self.settings("dynamic"): self.dfmHost = [] self.dynCns = [] self.target = [] self.harmonic = [] self.dynBone = [] parent = self._root for i, (bone, tfmA, tfmB) in enumerate(izip(self.bones, boneTfm, tgtTfm), start=1): dynCns = self.addRig(parent, "DynCns{}".format(i), tfmA, "cube", size=1) self.dynCns.append(dynCns) target = self.addRig(dynCns, "Target{}".format(i), tfmB, "null", size=1) self.target.append(target) harmonic = self.addRig(target, "Harmonic{}".format(i), tfmB, "diamond", size=1) self.harmonic.append(harmonic) dynBone = self.addRig(parent, "Dynamic{}".format(i), tfmA, "pyramid", size=1, ro=[0, 0, -90], so=[1, self.factor(), 1]) self.dynBone.append(dynBone) parent = dynBone self.dfmHost.append(dynBone) else: self.dfmHost = self.bones # Strap ---------------------------- if self.settings("strap"): endTfm = boneTfm[-1].copy(translation=positions[-1]) self.end = self.addRig(self.dfmHost[-1], "End", endTfm)