{"id":873,"date":"2019-06-04T23:55:24","date_gmt":"2019-06-04T21:55:24","guid":{"rendered":"http:\/\/stefan-loser.de\/wordpress\/?page_id=873"},"modified":"2021-01-31T21:36:21","modified_gmt":"2021-01-31T20:36:21","slug":"maya-python-ik-fk-auto-creator","status":"publish","type":"page","link":"https:\/\/stefan-loser.de\/?page_id=873","title":{"rendered":"Maya Python IK FK Switch Auto Creator"},"content":{"rendered":"\n<p>The following python script I wrote to speed up my rigging process. There are a lot of repetitive steps when rigging any type of object. Creating an IK FK switch for several joint chains of a character is one of them. This is a really short script and the usage at the bottom is specific to the naming conventions I use, but should be relatively easy to adjust.<\/p>\n\n\n\n<p>The first code snippet contains a method for duplicating an object. Furthermore all of it&#8217;s children and itself will be renamed based on the parameters. It searches for &#8216;oldSubString&#8217; and replaces it with &#8216;newSubString&#8217; while returning the duplicate object which is the highest one in the hierarchy.&nbsp; Renaming is one of major time consuming<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"godzilla\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import maya.cmds as cmds;\n\n###\n# duplicates the object with the name \"oldObjectName\" and replaces \"oldSubSring\" with \"newSubString\"\n###\ndef CreateRenamedDuplicate(oldObjectName,oldSubSring, newSubString):\n    newObj = cmds.duplicate(oldObjectName,renameChildren=True)\n    relatives = GetAllRelativesAndSelf(newObj[0])\n    \n    for name in relatives:\n        newName = name.replace(oldSubSring, newSubString)\n        cmds.rename(name,newName)\n        \n        if newObj[0] == name:\n            return newName<\/pre>\n\n\n\n<p>The next paragraph contains a method which returns an object and its relatives, quite small and neat.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"godzilla\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">###\n# returns an array of all relatives of a provided object plus itself\n###\ndef GetAllRelativesAndSelf(object):\n\n    relatives = cmds.listRelatives(object, c=True, ad=True)\n    relatives.append(object)\n    return relatives<\/pre>\n\n\n\n<p>And that&#8217;s already the last part of the switch functionality. This will create arrays of all the involved objects. So the base joints, the iks and the fks. Then it will create a group which holds an attribute for blending between ik or fk. Then it creates a blendcolor node which is pretty much a lerp.Then we connect the rotation attributes of the ik and fk chain to the base joints, making it so that the base joints are now fully in control of the two joint chains. If you want to see a visual result, just open up the graph editor. By doing all this, we sped up a <span data-dobid=\"hdw\">tedious process. <\/span><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"godzilla\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">###\n# creates attributes and connects them to setup a functional ik fk switch\n###\ndef CreateIKFKSwitch(resultObj, ikObj, fkObj):\n\u00a0\u00a0\u00a0 baseObjects = GetAllRelativesAndSelf(resultObj)\n\u00a0\u00a0\u00a0 IKObjects = GetAllRelativesAndSelf(ikObj)\n\u00a0\u00a0\u00a0 FKObjects = GetAllRelativesAndSelf(fkObj)\n\u00a0\u00a0\u00a0 counter = 0\n\u00a0\u00a0 \u00a0\n\u00a0\u00a0 \u00a0switchName = \"IK_FK_Switch\"\n\u00a0\u00a0 \u00a0attributeToConnectFrom = \"rotate\"\n\u00a0\u00a0 \u00a0attributeToConnectTo = \"color\"\n\n\u00a0\u00a0\u00a0 controlGroup = cmds.group( empty=True, name='IK_FK_BlendControls' )\n\u00a0\u00a0\u00a0 cmds.addAttr (controlGroup,longName=switchName, minValue=0, maxValue=1, defaultValue=0, attributeType=\"double\")\n\u00a0\u00a0\u00a0 cmds.setAttr(controlGroup + \".\"+switchName,edit=True, keyable=True)\n\n\u00a0\u00a0\u00a0 for obj in baseObjects:\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 blendColorNodeName = switchName + \"_\"+IKObjects[counter]+\"_\"+FKObjects[counter]\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 blendColors = cmds.shadingNode('blendColors',au=True,name=blendColorNodeName)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cmds.connectAttr(IKObjects[counter]+\".\"+ attributeToConnect,blendColors + \".\" + attributeToConnectTo + \"1\")\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cmds.connectAttr(FKObjects[counter]+\".\"+ attributeToConnect,blendColors+ \".\" + attributeToConnectTo + \"2\")\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cmds.connectAttr(blendColors+\".output\",baseObjects[counter]+\".\"+ attributeToConnect)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 cmds.connectAttr(controlGroup+\".\"+switchName,blendColors+\".blender\")\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 counter+=1;<\/pre>\n\n\n\n<p>At last all you need to do is create the individual chains and rename them. Then connect them all together. 50 lines of code which take away countless renaming , duplication and node creation steps. Maya&#8217;s API is really powerful, but the non-object oriented approach makes it quite hard at the start to understand how it wants to be used.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"godzilla\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">###\n# Executing the procedures\n###\nselection = cmds.ls(sl=True)\nikChain = CreateRenamedDuplicate(selection,\"_Jnt1\", \"_IK_jnt\")\nfkChain = CreateRenamedDuplicate(selection, \"_Jnt1\", \"_FK_jnt\")\nCreateIKFKSwitch(selection[0],ikChain,fkChain);\n\n<\/pre>\n\n\n\n<p>Thanks for reading! If you have any more questions, please drop me a message.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>On this page I&#8217;m writing about a small script which I&#8217;ve written for Maya&#8217;s Python to speed up my rigging workflow. <\/p>\n","protected":false},"author":1,"featured_media":1339,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"pgc_sgb_lightbox_settings":"","footnotes":""},"class_list":["post-873","page","type-page","status-publish","has-post-thumbnail","hentry"],"_links":{"self":[{"href":"https:\/\/stefan-loser.de\/index.php?rest_route=\/wp\/v2\/pages\/873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stefan-loser.de\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/stefan-loser.de\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/stefan-loser.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stefan-loser.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=873"}],"version-history":[{"count":8,"href":"https:\/\/stefan-loser.de\/index.php?rest_route=\/wp\/v2\/pages\/873\/revisions"}],"predecessor-version":[{"id":1291,"href":"https:\/\/stefan-loser.de\/index.php?rest_route=\/wp\/v2\/pages\/873\/revisions\/1291"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/stefan-loser.de\/index.php?rest_route=\/wp\/v2\/media\/1339"}],"wp:attachment":[{"href":"https:\/\/stefan-loser.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}