├── extra ├── sidCode.py ├── VN Skin Tools-logos_black.png ├── save_load_guides.py └── skin_tools.py ├── .DS_Store ├── main ├── .DS_Store ├── run.py ├── transform.py ├── ui.py ├── module.py └── py2.py ├── old_files ├── .DS_Store ├── skintools_v1.py ├── Vn_v1.py └── VnMagicTool_v2.py ├── .gitignore ├── AutoRiggingFramework.code-workspace └── README.md /extra/sidCode.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmehraajm/RiggingDev/HEAD/.DS_Store -------------------------------------------------------------------------------- /main/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmehraajm/RiggingDev/HEAD/main/.DS_Store -------------------------------------------------------------------------------- /old_files/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmehraajm/RiggingDev/HEAD/old_files/.DS_Store -------------------------------------------------------------------------------- /extra/VN Skin Tools-logos_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sidmehraajm/RiggingDev/HEAD/extra/VN Skin Tools-logos_black.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | main/__pycache__/module.cpython-37.pyc 3 | main/__pycache__/module.cpython-310.pyc 4 | AutoRiggingFramework.code-workspace 5 | *.pyc 6 | -------------------------------------------------------------------------------- /main/run.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import importlib 3 | 4 | sys.path.append( 5 | "/Users/siddarthmehraajm/Documents/GitHub/AutoRiggingFramework/RiggingDev/main" 6 | ) 7 | 8 | from ui import * 9 | import ui 10 | 11 | importlib.reload(ui) 12 | -------------------------------------------------------------------------------- /AutoRiggingFramework.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".." 5 | }, 6 | { 7 | "path": "." 8 | } 9 | ], 10 | "settings": { 11 | "[python]": { 12 | "editor.defaultFormatter": "ms-python.black-formatter" 13 | }, 14 | "python.formatting.provider": "none" 15 | } 16 | } -------------------------------------------------------------------------------- /extra/save_load_guides.py: -------------------------------------------------------------------------------- 1 | 2 | #guide_save & load 3 | import json 4 | import pymel.core as pm 5 | import maya.cmds as cmds 6 | class guides(object): 7 | #fileName = '/Users/siddarthmehraajm/Documents/GitHub/AutoRiggingFramework/TSL-codebase/Extra/cape.json' 8 | def __init__(self,filename=None): 9 | self.filename = filename 10 | 11 | def writeJson(self,dataToWrite,fileName): 12 | if '.json' not in fileName: 13 | fileName+='.json' 14 | 15 | print("> write to json file is seeing: {0}".format(fileName)) 16 | 17 | with open(fileName,'w') as jsonFile: 18 | json.dump(dataToWrite,jsonFile,indent = 2) 19 | 20 | print ("Data was successfully written to {0}".format(fileName)) 21 | return fileName 22 | 23 | 24 | 25 | def readJsonFile(self,fileName): 26 | try: 27 | with open(fileName,'r') as jsonFile: 28 | return json.load(jsonFile) 29 | except: 30 | raise RuntimeError("Could not read {0}".format(fileName)) 31 | 32 | def extract_data(self,obj = None): 33 | values = [] 34 | if obj: 35 | trs = cmds.getAttr('%s.translate'%obj) 36 | rot = cmds.getAttr('%s.rotate'%obj) 37 | scl = cmds.getAttr('%s.scale'%obj) 38 | values.append(trs) 39 | values.append(rot) 40 | values.append(scl) 41 | 42 | return values 43 | 44 | def save_guides_data(self,fileName): 45 | 46 | data_dict = {} 47 | 48 | gds = pm.ls('*_gd',an=1) 49 | for i in gds: 50 | data = self.extract_data(str(i)) 51 | data_dict[str(i)]= data 52 | 53 | jsn_file = self.writeJson(data_dict,fileName) 54 | 55 | 56 | def load_guides(self,fileName): 57 | 58 | data_dic = self.readJsonFile(fileName) 59 | keysList = list(data_dic.keys()) 60 | for i in keysList: 61 | pass 62 | pm.setAttr(i+'.translate',((data_dic[i])[0])[0]) 63 | pm.setAttr(i+'.rotate',((data_dic[i])[1])[0]) 64 | pm.setAttr(i+'.scale',((data_dic[i])[2])[0]) 65 | 66 | 67 | 68 | #save_guides_data(fileName) 69 | #load_guides(fileName) 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Maya Skinning Tool 2 | ### Tutorial on how to Use - 3 | https://youtu.be/wTVYchvHAuU 4 | 5 | ## Welcome to the Maya Skinning Tool Repository! 6 | 7 | This tool is a game-changer in the realm of character skin creation and enhancement within Autodesk Maya. Designed to streamline the process and provide users with unprecedented control over character rigs, the Maya Skinning Tool brings efficiency and versatility to your animation workflow. 8 | 9 | ## Features 10 | 11 | - **Easy Conversion:** Simplify the conversion of diverse objects and deformers into a cohesive skin setup, eliminating tedious manual adjustments. 12 | 13 | - **Seamless Integration:** Integrate new deformations seamlessly into existing skin configurations, providing unprecedented control over character rigs. 14 | 15 | - **Versatile Solution:** Whether enhancing existing skin or starting from scratch, this tool offers a versatile solution for character rigging, adapting to your workflow. 16 | 17 | - **Refined Deformations:** Witness the transformation of rough or blocking skin into a refined and smoothly deformable structure. 18 | 19 | ## Collaboration 20 | 21 | This tool is the result of a collaboration with the talented [Vishal Nagpal](https://github.com/vishal980-glitch), the visionary behind the system and its initial concept. Together, we've made the tool more robust, enhancing the character rigging experience. 22 | 23 | ## Getting Started 24 | 25 | ### Prerequisites 26 | 27 | - Autodesk Maya installed 28 | - Git installed 29 | 30 | ### Installation 31 | Tutorial Video on How to Install - 32 | https://youtu.be/jr6PCLixYdE 33 | 34 | For Python 3 - 35 | 1. Clone the repository: 36 | 37 | ```bash 38 | git clone https://github.com/sidmehraajm/RiggingDev.git 39 | ``` 40 | 41 | 2. Open the run file in Maya and replace the main(folder) path with your local path. 42 | 43 | 3. The tool can be added to the shelf or used from your script editor for easy access. 44 | 45 | 46 | For Python 2 - Directly copy the code from py2.py(Inside the main folder) and run, can be added to shelf for easy access 47 | ## Issues and Feedback 48 | 49 | If you encounter any issues or have feedback, please open an issue on the [Issues](https://github.com/sidmehraajm/RiggingDev/issues) tab. We appreciate your input and strive to improve the tool continuously. 50 | You can also contact me on Linkedin - (https://www.linkedin.com/in/siddarthmehraajm/) 51 | Feel free to explore the Maya Skinning Tool and elevate your character rigging workflow! Happy Rigging! 🎨✨ 52 | -------------------------------------------------------------------------------- /main/transform.py: -------------------------------------------------------------------------------- 1 | import pymel.core as pm 2 | import maya.cmds as cmds 3 | 4 | 5 | class JointProc: 6 | import pymel.core as pm 7 | 8 | cmdsSel = None 9 | sel = None 10 | 11 | def __init__(self): 12 | self.sel = pm.ls(sl=1) 13 | 14 | def getSelection(self, Pivs=cmdsSel): 15 | components = Pivs 16 | selList = [] 17 | objName = components[0][0 : components[0].index(".")] 18 | # go through every component in the list. If it is a single component ("pCube1.vtx[1]"), add it to the list. Else, 19 | # add each component in the index ("pCube1.vtx[1:5]") to the list 20 | for c in components: 21 | if ":" not in c: 22 | selList.append(c) 23 | else: 24 | startComponent = int(c[c.index("[") + 1 : c.index(":")]) 25 | endComponent = int(c[c.index(":") + 1 : c.index("]")]) 26 | componentType = c[c.index(".") + 1 : c.index("[")] 27 | while startComponent <= endComponent: 28 | selList.append( 29 | objName + "." + componentType + "[" + str(startComponent) + "]" 30 | ) 31 | startComponent += 1 32 | 33 | return selList 34 | pivsList.append(selList) 35 | 36 | def CtrJnt(self, Piv=sel): 37 | # createJoint 38 | 39 | sl = Piv 40 | try: 41 | pm.select(sl) 42 | tempPos = pm.cluster(n="Temp")[1] 43 | Jnt = pm.createNode("joint", n=(sl[0] + "Jnt")) 44 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 45 | pm.delete(tempPos) 46 | return Jnt 47 | 48 | except: 49 | tempPos = pm.createNode("transform", n="Temp") 50 | pm.delete(pm.parentConstraint(sl, tempPos)) 51 | Jnt = pm.createNode("joint", n=(sl[0] + "_Jnt")) 52 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 53 | pm.delete(tempPos) 54 | return Jnt 55 | 56 | def CtrJntEach(self, cmdsSel=None): 57 | # createJoint 58 | try: 59 | sl = getSelection() 60 | print(sl) 61 | 62 | except: 63 | sl = cmdsSel 64 | print(sl) 65 | 66 | jnts_tr = [] 67 | for i in sl: 68 | pass 69 | if pm.objectType(i) == "mesh": 70 | try: 71 | pm.select(i) 72 | tempPos = pm.cluster(n="Temp")[1] 73 | Jnt = pm.createNode("joint", n=(i + "Jnt")) 74 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 75 | pm.delete(tempPos) 76 | print(Jnt) 77 | 78 | except: 79 | tempPos = pm.createNode("transform", n="Temp") 80 | pm.delete(pm.parentConstraint(i, tempPos)) 81 | Jnt = pm.createNode("joint", n=(i + "_Jnt")) 82 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 83 | pm.delete(tempPos) 84 | print(Jnt) 85 | else: 86 | pm.select(i) 87 | tempPos = pm.cluster(n="Temp")[1] 88 | Jnt = pm.createNode("joint", n=(i + "Jnt")) 89 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 90 | pm.delete(tempPos) 91 | print(Jnt) 92 | 93 | def transfroms_to_curve(self, cmdsSel=None): 94 | p = [] 95 | trs = cmdsSel 96 | for i in trs: 97 | mtx = i.worldMatrix.get() 98 | tr = mtx.translate.get() 99 | p.append(tr) 100 | crv = pm.curve(d=3, p=p) 101 | -------------------------------------------------------------------------------- /extra/skin_tools.py: -------------------------------------------------------------------------------- 1 | import json, sys 2 | import pymel.core as pm 3 | import maya.cmds as cmds 4 | 5 | def getShape(node, intermediate = False): 6 | if pm.nodeType(node)=='transform': 7 | tr = pm.PyNode(node) 8 | trShape = tr.getShapes() 9 | resultShapes = [] 10 | for shape in trShape: 11 | isIntermediate = pm.getAttr('%s.intermediateObject'%shape) 12 | if intermediate and isIntermediate and pm.listConnections(shape, source = False): 13 | return str(shape) 14 | elif not intermediate and not isIntermediate: 15 | return str(shape) 16 | if trShape: 17 | return trShape[0] 18 | elif pm.nodeType(node) in ['mesh','nurbsCurve','nurbsSurface']: 19 | return str(node) 20 | return None 21 | 22 | 23 | 24 | def getSkinCluster(shape): 25 | shape = getShape(shape) 26 | skin= pm.ls(pm.listHistory(shape),typ='skinCluster') 27 | if skin: 28 | return str(skin[0]) 29 | raise RuntimeError('No SkinCluster found') 30 | 31 | 32 | 33 | def writeJson(dataToWrite,fileName): 34 | if '.json' not in fileName: 35 | fileName+='.json' 36 | 37 | print("> write to json file is seeing: {0}".format(fileName)) 38 | 39 | with open(fileName,'w') as jsonFile: 40 | json.dump(dataToWrite,jsonFile,indent = 2) 41 | 42 | print ("Data was successfully written to {0}".format(fileName)) 43 | 44 | return fileName 45 | 46 | 47 | 48 | 49 | 50 | 51 | def readJsonFile(fileName): 52 | try: 53 | with open(fileName,'r') as jsonFile: 54 | return json.load(jsonFile) 55 | except: 56 | raise RuntimeError("Could not read {0}".format(fileName)) 57 | 58 | 59 | class gatherData(object): 60 | 61 | def getShapeNode(self,shape): 62 | return(getShape(shape)) 63 | 64 | def getSkinClusterNode(self,shape): 65 | return(getSkinCluster(shape)) 66 | 67 | def getTransformNode(self,shape): 68 | if pm.nodeType(shape) == 'transform': 69 | return(shape) 70 | else: 71 | return(pm.listTransforms(shape)[0]) 72 | def getVtxRange(self,shape): 73 | 74 | vtxData = pm.polyEvaluate(getShape(shape),v=1) 75 | #main Result1 76 | vtxResult = [] 77 | for i in range(0,vtxData): 78 | vtxResult.append('%s.vtx[%s]'%(shape,i)) 79 | return (vtxResult) 80 | 81 | 82 | def getJntInfluences(self,shape): 83 | skinCl = pm.PyNode(getSkinCluster(shape)) 84 | jnts = skinCl.getInfluence() 85 | jntValues = [] 86 | for i in jnts: 87 | jntValues.append(str(i)) 88 | 89 | return(jntValues) 90 | 91 | def ExtractData(v=0,tn=0,sn=0,sCn=0,jInf =0,objName = ''): 92 | ''' 93 | vertex : v=1 94 | transformNode :tn=1 95 | shapeNode: sn=1 96 | skinClusteNOde:sCn=1 97 | jointInfluences: jInf=1 98 | objName = 'object name' 99 | ''' 100 | returnValues = [] 101 | 102 | data = gatherData() 103 | if v==1: 104 | returnValues.append(data.getVtxRange(objName)) 105 | if tn==1: 106 | returnValues.append(data.getTransformNode(objName)) 107 | if sn==1: 108 | returnValues.append(data.getShapeNode(objName)) 109 | if sCn==1: 110 | returnValues.append(data.getSkinClusterNode(objName)) 111 | if jInf==1: 112 | returnValues.append(data.getJntInfluences(objName)) 113 | return returnValues 114 | 115 | def getVtxWeights(vtxList=[],skinClusterNode ='',thresholdValue=0.001): 116 | ''' 117 | vertexList: vtxList=[] 118 | skinCLusterName: skinClusterNode ='' 119 | thresholdValue: thresholdValue=0.001 120 | ''' 121 | 122 | if len(vtxList) != 0 and skinClusterNode != "": 123 | vtxDict = {} 124 | for vtx in vtxList: 125 | infValue = cmds.skinPercent(skinClusterNode,vtx,q=1,v=1,ib =thresholdValue) 126 | #print (infValue) 127 | infNames = cmds.skinPercent(skinClusterNode,vtx,transform = None,q=1,ib =thresholdValue) 128 | #print (infNames) 129 | vtxDict[vtx]= zip(infNames,infValue) 130 | return vtxDict 131 | else: 132 | raise RuntimeError("No Vertices or SkinCluster passed") 133 | 134 | 135 | def export_deformer2(objectName='',filePath=''): 136 | if objectName =='' and filePath == '': 137 | raise RuntimeError("No object name specifide & no file path given") 138 | 139 | geoData = ExtractData(v=1,tn=1,sCn=1,jInf=1,objName = objectName) 140 | vtxData = geoData[0] 141 | geoName = geoData[1] 142 | skinClusterNode=geoData[2] 143 | thV = 0.001 144 | jntNames = geoData[-1] 145 | 146 | skinClusterDetails = [geoName,skinClusterNode,jntNames] 147 | vtxDict = getVtxWeights(vtxData,skinClusterNode) 148 | 149 | if skinClusterDetails: 150 | sknfilePath = filePath.split('.json')[0]+'_sknInfo.json' 151 | 152 | writeJson(dataToWrite = skinClusterDetails,fileName = sknfilePath) 153 | 154 | if vtxDict: 155 | writeJson(dataToWrite = vtxDict,fileName = filePath) 156 | 157 | 158 | 159 | def import_deformer2(filePath): 160 | importFile = filePath 161 | sknfilePath = filePath.split('.json')[0]+'_sknInfo.json' 162 | sys.stdout.write('importing from %s'%str(importFile)) 163 | 164 | skinData = readJsonFile(sknfilePath) 165 | 166 | MeshName = skinData[0] 167 | skinCLusterName = skinData[1] 168 | influenceJoints = skinData[-1] 169 | 170 | if not pm.objExists(MeshName): 171 | raise RuntimeError(str(MeshName)+' >> Mesh Not Found') 172 | for i in influenceJoints: 173 | if not pm.objExists(i): 174 | raise RuntimeError(str(i)+' >> joint Not Found') 175 | 176 | data = gatherData() 177 | try: 178 | oldSkin = data.getSkinClusterNode(MeshName) 179 | pm.delete(oldSkin) 180 | print('Removing existing skin Cluster on the object named') 181 | except: 182 | pass 183 | 184 | 185 | pm.skinCluster(influenceJoints,MeshName,n = skinCLusterName) 186 | pm.select(cl=1) 187 | 188 | #loading vtxweights 189 | 190 | filevtxData = readJsonFile(importFile) 191 | if len(filevtxData)>0: 192 | 193 | for key in filevtxData.keys(): 194 | try: 195 | pm.skinPercent(skinCLusterName,key,tv=filevtxData[key],zri=1) 196 | except: 197 | raise RuntimeError('Issue while loading weights can be - Vertex not found or mesh changed') 198 | 199 | else: 200 | pm.error('JSON file is empty') 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | ''' 212 | export_deformer2(objectName,filePath) 213 | 214 | import_deformer2(filePath) 215 | 216 | objectName = 'qq' 217 | 218 | filePath = "E:/tst.json" 219 | 220 | exportWeightsJSON('s','asd') 221 | a = getVtxWeights(vtxList,skinClusterNode) 222 | 223 | data = gatherData() 224 | vtxList =data.getVtxRange('pCone1') 225 | skinClusterNode = data.getSkinClusterNode('pCone1') 226 | 227 | v =['a','bv','c'] 228 | g = ['1','2','3'] 229 | a = zip(v,g) 230 | a = list(a) 231 | 232 | ''' 233 | 234 | -------------------------------------------------------------------------------- /main/ui.py: -------------------------------------------------------------------------------- 1 | import maya.cmds as cmds 2 | import pymel.core as pm 3 | import importlib 4 | import pymel.core as pm 5 | import maya.cmds as cmds 6 | import pymel.core as pm 7 | import sys 8 | import importlib as imp 9 | import time 10 | 11 | 12 | import transform as tr 13 | import module as m 14 | 15 | imp.reload(tr) 16 | imp.reload(m) 17 | # sys.path.append('/Users/siddarthmehraajm/Documents/GitHub/AutoRiggingFramework/RiggingDev/main') 18 | 19 | # window 20 | win_name = "vn_skin_tools" 21 | win_title = "VN Skin Tools" 22 | win_size = (330, 290) 23 | if pm.window(win_name, q=1, exists=True): 24 | pm.deleteUI(win_name, window=True) 25 | 26 | """ 27 | if pm.windowPref(win_name,q=1 ,exists=True ): 28 | pm.windowPref(win_name, r=0 ) 29 | """ 30 | pm.window( 31 | win_name, 32 | title=win_title, 33 | widthHeight=win_size, 34 | sizeable=False, 35 | bgc=[(0.2), (0.2), (0.2)], 36 | ) 37 | 38 | Tab = pm.tabLayout("Tabs", p=win_name, tc=0, stb=1, snt=0) 39 | 40 | deformer_form = pm.formLayout("Converter", parent="Tabs") 41 | skin_utils_form = pm.formLayout("Import/Export", en=0, vis=0) 42 | utils_form = pm.formLayout("Utilities", parent="Tabs") 43 | about_form = pm.formLayout("About", parent="Tabs") 44 | 45 | # output_win_frame = pm.formLayout("MirrorWeights", parent="Tabs") 46 | 47 | 48 | radio_layout = pm.rowColumnLayout(nc=2, p=deformer_form, cal=[2, "left"], h=55) 49 | radio_coll = pm.radioCollection(parent=radio_layout) 50 | crv_to_skn_btn = pm.radioButton( 51 | "crv_skn_rb", l="Curve To Skin", p=radio_layout, sl=1, cc="crv_skn_cc()" 52 | ) 53 | softsel_to_skn = pm.radioButton( 54 | "softsel_skn_rb", l="Soft Selection To Skin", p=radio_layout, cc="softSel_skn_cc()" 55 | ) 56 | cluster_to_skn = pm.radioButton( 57 | "cls_skn_rb", l="Cluster To Skin", p=radio_layout, cc="cl_skn_cc()" 58 | ) 59 | df_to_skn_btn = pm.radioButton( 60 | "restdf_skn_rb", l="Wire/Wrap/Lattice", p=radio_layout, cc="df_skn_cc()" 61 | ) # /DeltaMush 62 | blendshape_to_skn = pm.radioButton( 63 | "bs_skn_rb", l="Blendshape To Skin", cc="blend_to_skin_cc()", p=radio_layout 64 | ) 65 | 66 | blocking_to_skin = pm.radioButton( 67 | "smooth_skn_rb", 68 | l="Blocking to Smooth Skin", 69 | cc="delta_to_skin_cc()", 70 | p=radio_layout, 71 | ) 72 | 73 | informatipn_txt_f = pm.textField( 74 | "info_txtf", 75 | w=180, 76 | h=25, 77 | p=deformer_form, 78 | en=0, 79 | pht="Add a Skinned Curve and Mesh", 80 | nbg=1, 81 | ) 82 | 83 | mesh_textfield = pm.textField( 84 | "mesh_field", w=180, h=35, pht="Add Mesh", p=deformer_form 85 | ) 86 | deformer_textfield = pm.textField( 87 | "df_field", w=180, h=35, pht="Add Skinned Curve", p=deformer_form 88 | ) 89 | 90 | 91 | add_mesh_btn = pm.button( 92 | "mesh_btn", l="Select Mesh", p=deformer_form, w=120, h=34, c="mesh_add()" 93 | ) 94 | add_df_btn = pm.button( 95 | "df_btn", l="Select Deformer", p=deformer_form, w=120, h=34, c="deformer_add()" 96 | ) 97 | convert_btn = pm.iconTextButton( 98 | "cvt_btn", 99 | style="iconAndTextHorizontal", 100 | image1="polyColorSetEditor.png", 101 | label="Convert to Skin", 102 | p=deformer_form, 103 | w=130, 104 | h=40, 105 | bgc=[(0.33), (0.33), (0.353)], 106 | c="convert_to_skin()", 107 | ) 108 | time_elapsed_txf = pm.textField( 109 | "time_txtf", 110 | w=80, 111 | h=25, 112 | p=deformer_form, 113 | en=0, 114 | pht="Time Elapsed: ", 115 | nbg=1, 116 | ) 117 | 118 | pm.formLayout( 119 | deformer_form, 120 | e=1, 121 | attachForm=[ 122 | (radio_layout, "top", 10), 123 | (informatipn_txt_f, "top", 67), 124 | (mesh_textfield, "top", 97), 125 | (deformer_textfield, "top", 135), 126 | (add_mesh_btn, "top", 98), 127 | (add_df_btn, "top", 136), 128 | (time_elapsed_txf, "top", 235), 129 | (convert_btn, "top", 190), 130 | (informatipn_txt_f, "left", 10), 131 | (radio_layout, "left", 10), 132 | (mesh_textfield, "left", 10), 133 | (deformer_textfield, "left", 10), 134 | (time_elapsed_txf, "left", 90), 135 | (convert_btn, "left", 95), 136 | (informatipn_txt_f, "right", 10), 137 | (add_mesh_btn, "right", 10), 138 | (add_df_btn, "right", 10), 139 | (time_elapsed_txf, "right", 50), 140 | ], 141 | ) 142 | 143 | skinCLusterName = pm.scrollField( 144 | "skn_cl_name", 145 | w=300, 146 | h=30, 147 | p=skin_utils_form, 148 | bgc=[(0.17), (0.18), (0.19)], 149 | editable=True, 150 | wordWrap=False, 151 | ) 152 | selc_mesh_btn = pm.button( 153 | "select_mesh", 154 | l="1. Select Mesh", 155 | p=skin_utils_form, 156 | w=150, 157 | h=30, 158 | bgc=[(0.2), (0.2), (0.2)], 159 | en=1, 160 | ) 161 | rename_skn_btn = pm.button( 162 | "rename_skn", 163 | l="2. Rename SkinC", 164 | p=skin_utils_form, 165 | w=150, 166 | h=30, 167 | bgc=[(0.2), (0.2), (0.2)], 168 | en=1, 169 | ) 170 | 171 | path_textfield = pm.textField( 172 | "df_field", 173 | w=180, 174 | h=41, 175 | pht="Add Deformer", 176 | p=skin_utils_form, 177 | bgc=[(0.17), (0.18), (0.19)], 178 | ) 179 | selectPath_button = pm.iconTextButton( 180 | "df_btn", 181 | style="iconAndTextHorizontal", 182 | l="Select path", 183 | p=skin_utils_form, 184 | w=120, 185 | h=40, 186 | bgc=[(0.2), (0.2), (0.2)], 187 | en=1, 188 | ) 189 | 190 | import_skn_button = pm.iconTextButton( 191 | "imp_skn", 192 | style="iconAndTextHorizontal", 193 | l="Import Deformer", 194 | p=skin_utils_form, 195 | w=150, 196 | h=40, 197 | bgc=[(0.2), (0.2), (0.2)], 198 | en=1, 199 | ) 200 | export_skn_button = pm.iconTextButton( 201 | "exp_skn ", 202 | style="iconAndTextHorizontal", 203 | l="Export Deformer", 204 | p=skin_utils_form, 205 | w=150, 206 | h=40, 207 | bgc=[(0.2), (0.2), (0.2)], 208 | en=1, 209 | ) 210 | 211 | pm.formLayout( 212 | skin_utils_form, 213 | e=1, 214 | attachForm=[ 215 | (skinCLusterName, "top", 10), 216 | (selc_mesh_btn, "top", 45), 217 | (rename_skn_btn, "top", 45), 218 | (import_skn_button, "top", 125), 219 | (export_skn_button, "top", 125), 220 | (path_textfield, "top", 80), 221 | (selectPath_button, "top", 80), 222 | (path_textfield, "left", 10), 223 | (skinCLusterName, "left", 10), 224 | (import_skn_button, "left", 11), 225 | (selc_mesh_btn, "left", 11), 226 | (rename_skn_btn, "right", 11), 227 | (selectPath_button, "right", 10), 228 | (export_skn_button, "right", 10), 229 | ], 230 | ) 231 | 232 | jnt_btwn_btn = pm.button( 233 | "jnt_btwn_btn", 234 | l="Joint at Center", 235 | p=utils_form, 236 | w=290, 237 | h=50, 238 | bgc=[(0.2), (0.21), (0.2)], 239 | en=1, 240 | c="jnt_btwn()", 241 | ) 242 | jnt_each_btn = pm.button( 243 | "jnt_each_btn", 244 | l="Joint at each selection (Supports Mesh)", 245 | p=utils_form, 246 | w=290, 247 | h=50, 248 | bgc=[(0.2), (0.21), (0.2)], 249 | en=1, 250 | c="jnt_each()", 251 | ) 252 | tr_to_crv_btn = pm.button( 253 | "tr_to_crv_btn", 254 | l="Transfrom to Curve", 255 | p=utils_form, 256 | w=290, 257 | h=50, 258 | bgc=[(0.2), (0.21), (0.2)], 259 | en=1, 260 | c="tr_crv()", 261 | ) 262 | pm.formLayout( 263 | utils_form, 264 | e=1, 265 | attachForm=[ 266 | (jnt_btwn_btn, "top", 10), 267 | (jnt_each_btn, "top", 69), 268 | (tr_to_crv_btn, "top", 130), 269 | (jnt_btwn_btn, "left", 10), 270 | (jnt_each_btn, "left", 10), 271 | (tr_to_crv_btn, "left", 10), 272 | (jnt_btwn_btn, "right", 10), 273 | (jnt_each_btn, "right", 10), 274 | (tr_to_crv_btn, "right", 10), 275 | ], 276 | ) 277 | about_txf = pm.button( 278 | "about_txf", 279 | w=290, 280 | h=50, 281 | l="Authors:\nVishal Nagpal\nSiddarth Mehra", 282 | p=about_form, 283 | en=1, 284 | bgc=[0.5, 0.7, 0.7], 285 | c="pm.launch(web='https://www.linkedin.com/in/vishal-nagpal-82975a149/')", 286 | ) 287 | link_btnSid = pm.button( 288 | "lnkSid", 289 | w=290, 290 | h=25, 291 | l="LinkedIn(Siddarth)", 292 | p=about_form, 293 | en=1, 294 | bgc=[0.2, 0.4, 0.76], 295 | c="pm.launch(web='https://www.linkedin.com/in/siddarthmehraajm/')", 296 | ) 297 | 298 | link_btnVish = pm.button( 299 | "lnkVish", 300 | w=290, 301 | h=25, 302 | l="LinkedIn(Vishal)", 303 | p=about_form, 304 | en=1, 305 | bgc=[0.2, 0.4, 0.76], 306 | c="pm.launch(web='https://www.linkedin.com/in/vishal-nagpal-82975a149/')", 307 | ) 308 | 309 | how_to_btn = pm.button( 310 | "how_to_btn", 311 | w=290, 312 | h=50, 313 | l="How to Use This Tool (Youtube Demo)", 314 | p=about_form, 315 | en=1, 316 | bgc=[0.6, 0.12, 0.12], 317 | c="pm.launch(web='https://youtu.be/wTVYchvHAuU/')", 318 | ) 319 | 320 | 321 | pm.formLayout( 322 | about_form, 323 | e=1, 324 | attachForm=[ 325 | (about_txf, "top", 10), 326 | (link_btnVish, "top", 97), 327 | (link_btnSid, "top", 67), 328 | (how_to_btn, "top", 130), 329 | (about_txf, "left", 10), 330 | (link_btnVish, "left", 10), 331 | (link_btnSid, "left", 10), 332 | (how_to_btn, "left", 10), 333 | (about_txf, "right", 10), 334 | (link_btnVish, "right", 10), 335 | (link_btnSid, "right", 10), 336 | (how_to_btn, "right", 10), 337 | ], 338 | ) 339 | 340 | 341 | pm.showWindow(win_name) 342 | 343 | 344 | # radio button change 345 | def crv_skn_cc(): 346 | pm.button(add_mesh_btn, e=1, en=1) 347 | pm.button(add_df_btn, e=1, en=1) 348 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 349 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Skinned Curve") 350 | pm.textField( 351 | informatipn_txt_f, e=1, ed=0, nbg=1, pht="Add a Skinned Curve and Mesh" 352 | ) 353 | 354 | 355 | def softSel_skn_cc(): 356 | pm.button(add_mesh_btn, e=1, en=0) 357 | pm.button(add_df_btn, e=1, en=0) 358 | pm.textField(mesh_textfield, e=1, en=0, pht=" ") 359 | pm.textField(deformer_textfield, e=1, en=0, pht=" ") 360 | pm.textField( 361 | informatipn_txt_f, 362 | e=1, 363 | ed=0, 364 | nbg=1, 365 | pht="Select Verticies/Face with soft selection", 366 | ) 367 | 368 | 369 | def cl_skn_cc(): 370 | pm.button(add_mesh_btn, e=1, en=1) 371 | pm.button(add_df_btn, e=1, en=1) 372 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 373 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Cluster") 374 | pm.textField(informatipn_txt_f, e=1, ed=0, nbg=1, pht="Add a Cluster and Mesh") 375 | 376 | 377 | def df_skn_cc(): 378 | pm.button(add_mesh_btn, e=1, en=1) 379 | pm.button(add_df_btn, e=1, en=1) 380 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 381 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Deformer") 382 | pm.textField( 383 | informatipn_txt_f, 384 | e=1, 385 | ed=0, 386 | nbg=1, 387 | pht="Add Wire/Wrap/Lattice/DeltaMush and a Mesh", 388 | ) 389 | 390 | 391 | def delta_to_skin_cc(): 392 | pm.button(add_mesh_btn, e=1, en=1) 393 | pm.button(add_df_btn, e=1, en=0) 394 | pm.textField(mesh_textfield, e=1, en=1, pht=" ") 395 | pm.textField(deformer_textfield, e=1, en=0, pht=" ") 396 | pm.textField( 397 | informatipn_txt_f, 398 | e=1, 399 | ed=0, 400 | nbg=1, 401 | pht="Add delta mush, delete delta after conversion", 402 | ) 403 | 404 | 405 | def blend_to_skin_cc(): 406 | pm.button(add_mesh_btn, e=1, en=1) 407 | pm.button(add_df_btn, e=1, en=0) 408 | pm.textField(mesh_textfield, e=1, en=1, pht=" ") 409 | pm.textField(deformer_textfield, e=1, en=0, pht=" ") 410 | pm.textField( 411 | informatipn_txt_f, 412 | e=1, 413 | ed=0, 414 | nbg=1, 415 | pht="Select mesh with BS, first bs will be converted", 416 | ) 417 | 418 | 419 | # convert functions 420 | 421 | 422 | class con_to_skn: 423 | def __init__(self): 424 | self.msh = None 425 | self.defr = None 426 | 427 | def add_mesh(self): 428 | try: 429 | Mymsh = str(pm.ls(sl=1)[0]) 430 | if pm.objectType(pm.ls(pm.listHistory(Mymsh), typ="mesh")[0]) == "mesh": 431 | pm.textField("mesh_field", e=1, tx=Mymsh) 432 | self.msh = Mymsh 433 | return self.msh 434 | 435 | except: 436 | pm.error("Please select a Mesh") 437 | 438 | def add_deformer(self): 439 | try: 440 | Mydefr = str(pm.ls(sl=1)[0]) 441 | option_functions = { 442 | "crv_skn_rb": "curve", 443 | "softsel_skn_rb": "soft", 444 | "restdf_skn_rb": "rest", 445 | "cls_skn_rb": "cluster", 446 | "bs_skn_rb": "blend", 447 | "smooth_skn_rb": "delta", 448 | } 449 | option = pm.radioCollection(radio_coll, q=1, sl=1) 450 | 451 | if option in option_functions: 452 | if option_functions[option] == "curve": 453 | if ( 454 | pm.objectType( 455 | pm.ls(pm.listHistory(Mydefr), typ="nurbsCurve")[0] 456 | ) 457 | == "nurbsCurve" 458 | ): 459 | pm.textField("df_field", e=1, tx=Mydefr) 460 | print(Mydefr) 461 | self.defr = Mydefr 462 | return self.defr 463 | elif option_functions[option] == "cluster": 464 | if ( 465 | pm.objectType( 466 | pm.ls(pm.listHistory(Mydefr), typ="clusterHandle")[0] 467 | ) 468 | == "clusterHandle" 469 | ): 470 | pm.textField("df_field", e=1, tx=Mydefr) 471 | print(Mydefr) 472 | self.defr = Mydefr 473 | return self.defr 474 | 475 | elif option_functions[option] == "soft": 476 | pm.textField("df_field", e=1, tx=Mydefr) 477 | self.defr = Mydefr 478 | return self.defr 479 | 480 | elif option_functions[option] == "rest": 481 | pm.textField("df_field", e=1, tx=Mydefr) 482 | self.defr = Mydefr 483 | return self.defr 484 | elif option_functions[option] == "delta": 485 | pm.textField("df_field", e=1, tx=Mydefr) 486 | self.defr = Mydefr 487 | return self.defr 488 | elif option_functions[option] == "blend": 489 | pm.textField("df_field", e=1, tx=Mydefr) 490 | self.defr = Mydefr 491 | return self.defr 492 | 493 | except: 494 | pm.error("Please select the correct Deformer/Node") 495 | 496 | def main_convert_to_skin(self): 497 | print(self.defr, self.msh) 498 | dc = m.deformerConvert(deformer=self.defr, mesh=self.msh) 499 | dc.deformer_skin_convert() 500 | 501 | def rest_deformer(self): 502 | print(self.defr, self.msh) 503 | dc = m.deformerConvert(deformer=self.defr, mesh=self.msh) 504 | dc.rest_deformer_skin_convert() 505 | 506 | def SoftSelection(self): 507 | print(self.defr, self.msh) 508 | dc = m.deformerConvert(deformer=self.defr, mesh=self.msh) 509 | dc.SoftSelectionToConvert() 510 | 511 | def convert_cluster(self): 512 | print(self.defr, self.msh) 513 | dc = m.deformerConvert(deformer=self.defr, mesh=self.msh) 514 | dc.ClusterConvert() 515 | 516 | def delta_skin(self): 517 | print(self.defr, self.msh) 518 | dc = m.deformerConvert(deformer=self.defr, mesh=self.msh) 519 | dc.deltaMush_skin_convert() 520 | 521 | def blend_skin(self): 522 | print(self.defr, self.msh) 523 | dc = m.deformerConvert(deformer=self.defr, mesh=self.msh) 524 | dc.blendShapeConvert() 525 | 526 | 527 | # button functions 528 | 529 | 530 | def jnt_btwn(): 531 | t = tr.JointProc() 532 | t.CtrJnt(cmds.ls(sl=1)) 533 | 534 | 535 | def jnt_each(): 536 | t = tr.JointProc() 537 | t.CtrJntEach(cmds.ls(sl=1, fl=1)) 538 | 539 | 540 | def tr_crv(): 541 | t = tr.JointProc() 542 | t.transfroms_to_curve(pm.ls(sl=1)) 543 | 544 | 545 | con = con_to_skn() 546 | 547 | 548 | def mesh_add(): 549 | c = con.add_mesh() 550 | 551 | 552 | def deformer_add(): 553 | c = con.add_deformer() 554 | 555 | 556 | def convert_to_skin(): 557 | pm.textField(time_elapsed_txf, e=1, ed=0, nbg=1, pht="Time Elapsed:") 558 | start = time.time() 559 | option_functions = { 560 | "crv_skn_rb": con.main_convert_to_skin, 561 | "softsel_skn_rb": con.SoftSelection, 562 | "restdf_skn_rb": con.rest_deformer, 563 | "cls_skn_rb": con.convert_cluster, 564 | "smooth_skn_rb": con.delta_skin, 565 | "bs_skn_rb": con.blend_skin, 566 | } 567 | option = pm.radioCollection(radio_coll, q=1, sl=1) 568 | 569 | if option in option_functions: 570 | c = option_functions[option]() 571 | else: 572 | print("Option is wip") 573 | end = time.time() 574 | pm.textField( 575 | time_elapsed_txf, 576 | e=1, 577 | ed=0, 578 | nbg=1, 579 | pht="Time Elapsed:%d seconds" % (end - start), 580 | ) 581 | print("Total time elapsed_%d" % (end - start)) 582 | -------------------------------------------------------------------------------- /main/module.py: -------------------------------------------------------------------------------- 1 | import maya.OpenMaya as om 2 | import pymel.core as pm 3 | import maya.cmds as cmds 4 | import time 5 | import math 6 | import sys 7 | 8 | """ 9 | 10 | ui 11 | query definations - selection check error 12 | find data 13 | create curve from transforms 14 | one defination for all deformer----* 15 | skin cluster utils 16 | export/import- skin/deformers 17 | copy skin 18 | vertex weight slider 19 | mirror deformer weight 20 | """ 21 | 22 | 23 | class utils: 24 | def __init__(self, object=None): 25 | self.obj = object 26 | 27 | def CreateCrv(self): 28 | crv = cmds.curve(p=[cmds.xform(d, t=1, q=1, ws=1) 29 | for d in cmds.ls(sl=1)]) 30 | cmds.setAttr(crv+".dispCV", 1) 31 | 32 | def softSelection(self): 33 | selection = om.MSelectionList() 34 | softSelection = om.MRichSelection() 35 | om.MGlobal.getRichSelection(softSelection) 36 | softSelection.getSelection(selection) 37 | 38 | dagPath = om.MDagPath() 39 | component = om.MObject() 40 | 41 | iter = om.MItSelectionList(selection, om.MFn.kMeshVertComponent) 42 | elements = [] 43 | while not iter.isDone(): 44 | iter.getDagPath(dagPath, component) 45 | dagPath.pop() 46 | fnComp = om.MFnSingleIndexedComponent(component) 47 | for i in range(fnComp.elementCount()): 48 | elements.append( 49 | [fnComp.element(i), fnComp.weight(i).influence()]) 50 | iter.next() 51 | return elements 52 | 53 | 54 | class getData: 55 | """ 56 | A class for extracting information and performing calculations related to deformations. 57 | """ 58 | 59 | def __init__(self, object=None): 60 | self.obj = object 61 | 62 | def get_skinCluster(self): 63 | """ 64 | Get the skinCluster associated with the object. 65 | 66 | Returns: 67 | skinCluster (str or None): The name of the skinCluster or None if not found. 68 | 69 | """ 70 | pyObj = pm.PyNode(self.obj) 71 | try: 72 | self.skn = pm.ls(pm.listHistory(pyObj), typ="skinCluster")[0] 73 | return self.skn 74 | 75 | except: 76 | return None 77 | 78 | def get_influnced_joints(self, skin_node=None): 79 | """ 80 | Get the list of influenced joints by a given skinCluster. 81 | 82 | Args: 83 | skin_node (str): The name of the skinCluster. 84 | 85 | Returns: 86 | influences (list or None): A list of influenced joint names or None if not found. 87 | 88 | """ 89 | try: 90 | self.influences = pm.skinCluster(skin_node, inf=True, q=True) 91 | return self.influences 92 | 93 | except: 94 | # pm.error('No skinCluster found!') 95 | pass 96 | 97 | def solvVert(self, vertcnt): 98 | """ 99 | Extract vertex numbers from vertex count strings. 100 | 101 | Args: 102 | vertcnt (list): List of vertex count strings. 103 | 104 | Returns: 105 | totalCounts (list): List of extracted vertex numbers as strings. 106 | 107 | """ 108 | totalCounts = [] 109 | 110 | for vert in vertcnt: 111 | split01 = vert.split("[") 112 | split02 = split01[-1].split("]") 113 | start = int(split02[0]) 114 | 115 | totalCounts.append(str(start)) 116 | 117 | return totalCounts 118 | 119 | def effectedVertNumber(self, meshClust, unlockJt): 120 | """ 121 | Calculate the affected vertex numbers when a joint is unlocked in a skinCluster. 122 | 123 | Args: 124 | meshClust (str): The name of the skinCluster. 125 | unlockJt (str): The name of the joint to be unlocked. 126 | 127 | Returns: 128 | vertNumb (list): List of affected vertex numbers as strings. 129 | 130 | """ 131 | vertNumb = [] 132 | pm.select(cl=1) 133 | pm.skinCluster(meshClust, e=True, siv=unlockJt) 134 | effectdVrt0 = cmds.ls(sl=True, fl=1) 135 | vertNumb = getData().solvVert(effectdVrt0) 136 | cmds.select(d=1) 137 | 138 | return vertNumb 139 | 140 | def getUnlockedJnt(self, mesh_joinds): 141 | """ 142 | Find and return joints that are unlocked among a list of joints. 143 | 144 | Args: 145 | mesh_joints (list): List of joint names to check. 146 | 147 | Returns: 148 | unlockJnd (list): List of unlocked joint names. 149 | 150 | Raises: 151 | pm.error: If no joint is unlocked or if more than one joint is unlocked. 152 | 153 | """ 154 | unlockJnd = [] 155 | for n in mesh_joinds: 156 | findlock = pm.getAttr(n + ".liw") 157 | if findlock == False: 158 | unlockJnd.append(n) 159 | 160 | if unlockJnd == []: 161 | pm.error("Please unlock one joint for distributing the weight") 162 | 163 | if len(unlockJnd) > 1: 164 | pm.error("Only one joint should be unlocked") 165 | 166 | return unlockJnd 167 | 168 | # ---------------------------------------------------Distance between two vertex 169 | 170 | def VertDistance(self, meshNam, VertNumList, moverNam, moveType=".rotatePivot", BS=False, WeightName=None): 171 | """ 172 | Calculate the distances between two sets of vertices on a mesh. 173 | 174 | Args: 175 | mesh_name (str): The name of the mesh. 176 | vert_num_list (list): List of vertex numbers as strings. 177 | mover_name (str): The name of the mover object. 178 | 179 | Returns: 180 | Distance (list): List of distances between vertices. 181 | 182 | """ 183 | old_PoseVert = [] 184 | New_PoseVert = [] 185 | Distance = [] 186 | 187 | for xyz in [0, 1, 2]: 188 | set_01Z = [] 189 | 190 | for d in VertNumList: 191 | Attr = pm.xform(meshNam + ".vtx[" + d + "]", q=True, ws=True, t=True)[ 192 | xyz 193 | ] 194 | 195 | set_01Z.append((Attr)) 196 | pm.select(d=True) 197 | 198 | old_PoseVert.append(set_01Z) 199 | 200 | if BS == False: 201 | pm.move(1, moverNam + moveType, y=True, r=True) 202 | else: 203 | pm.setAttr(moverNam[0] + '.' + WeightName[0], 0) 204 | 205 | for xyz in [0, 1, 2]: 206 | set_02Z = [] 207 | 208 | for b in VertNumList: 209 | Attrs = pm.xform(meshNam + ".vtx[" + b + "]", q=True, ws=True, t=True)[ 210 | xyz 211 | ] 212 | 213 | set_02Z.append((Attrs)) 214 | pm.select(d=True) 215 | 216 | New_PoseVert.append(set_02Z) 217 | 218 | if BS == False: 219 | pm.move(-1, moverNam + moveType, y=True, r=True) 220 | else: 221 | pm.setAttr(moverNam[0] + '.' + WeightName[0], 1) 222 | 223 | for o in range(len(VertNumList)): 224 | x1, y1, z1 = ( 225 | float(old_PoseVert[0][o]), 226 | float(old_PoseVert[1][o]), 227 | float(old_PoseVert[2][o]), 228 | ) 229 | x2, y2, z2 = ( 230 | float(New_PoseVert[0][o]), 231 | float(New_PoseVert[1][o]), 232 | float(New_PoseVert[2][o]), 233 | ) 234 | 235 | Distance.append( 236 | math.sqrt( 237 | ((x1 - x2) * (x1 - x2)) 238 | + ((y1 - y2) * (y1 - y2)) 239 | + ((z1 - z2) * (z1 - z2)) 240 | ) 241 | ) 242 | 243 | return Distance 244 | 245 | # ---------------------------------------------------percentage_find 246 | 247 | def WeightByOnePercentage(self, distance, hold_skin): 248 | """ 249 | Calculate weight values based on distances and skinCluster weights. 250 | 251 | Args: 252 | distance (list): List of distances between vertices. 253 | hold_skin (list): List of skinCluster weights. 254 | 255 | Returns: 256 | percentage (list): List of weight values. 257 | 258 | """ 259 | percentage = [] 260 | 261 | for nnn in range(len(hold_skin)): 262 | Onepercentage = (hold_skin[nnn] / 1.0) * distance[nnn] 263 | percentage.append(Onepercentage) 264 | 265 | return percentage 266 | 267 | # --------------------------------------------------- check deformer Type 268 | def deformerType(self, Name): 269 | """ 270 | Identify and return the type of deformer applied to an object. 271 | 272 | Args: 273 | name (str): The name of the object. 274 | 275 | Returns: 276 | deformer_type (str): The type of deformer (e.g., 'wire', 'lattice', 'cluster', 'wrap', 'blendShape'). 277 | 278 | """ 279 | nodes = [] 280 | 281 | for dfm in cmds.listHistory(Name): 282 | if cmds.nodeType(dfm) == "wire": 283 | pm.setAttr(dfm + ".rotation", 0.0) 284 | nodes.append("wire") 285 | if cmds.nodeType(dfm) == "lattice": 286 | nodes.append("lattice") 287 | if cmds.nodeType(dfm) == "cluster": 288 | nodes.append("cluster") 289 | if cmds.nodeType(dfm) == "wrap": 290 | nodes.append("wrap") 291 | if cmds.nodeType(dfm) == "blendShape": 292 | nodes.append("blendShape") 293 | if cmds.nodeType(dfm) == "deltaMesh": 294 | nodes.append("deltaMesh") 295 | 296 | return nodes[0] 297 | 298 | def NewJnt(self, positonN, MeshNam): 299 | cmds.select(d=True) 300 | objList = cmds.ls(MeshNam + "_*_Jnt") 301 | number = [int(i.split("_")[1]) for i in objList] 302 | 303 | nList = [] 304 | for i in range(1, len(number)+2): 305 | if i not in number: 306 | nList.append(i) 307 | 308 | jntt = cmds.joint(n=MeshNam + "_" + 309 | str(nList[0]).zfill(3) + "_Jnt", p=positonN) 310 | cmds.select(d=True) 311 | return jntt 312 | 313 | def BlendShape(self, Nam): 314 | 315 | list = cmds.listHistory(Nam, lv=1) 316 | nodes = [i for i in list if pm.nodeType(i) == 'blendShape'] 317 | return nodes 318 | 319 | def check_connections(self, obj): 320 | attributes = ['tx', 'ty', 'tz', 321 | 'rx', 'ry', 'rz', 322 | 'sx', 'sy', 'sz'] 323 | 324 | for i in attributes: 325 | keys = cmds.keyframe(obj + '.' + i, query=True) 326 | if keys: 327 | print('Please remove all keyframes on joints') 328 | 329 | '''constraints = cmds.listConnections(obj + '.' + i, type='constraint') 330 | if constraints: 331 | print('Please remove all constraints on joints') 332 | 333 | connections = cmds.listConnections(obj + '.' + i, plugs=True) 334 | if connections: 335 | print('Please remove all connections on joints')''' 336 | 337 | 338 | class deformerConvert(getData): 339 | """ 340 | Main class for converting deformers to skincluster. 341 | 342 | Args: 343 | deformer (str, optional): The name of the deformer to be converted. 344 | mesh (str, optional): The name of the mesh to be processed. 345 | 346 | Attributes: 347 | deformer (str): The name of the deformer being converted. 348 | mesh (str): The name of the mesh being processed. 349 | hold_joint (str or None): The name of the hold joint created or None. 350 | meshCluster (str or None): The name of the mesh's skinCluster or None. 351 | vertNumber (list): List of vertex numbers as strings. 352 | hold_skin_value (list): List of hold joint's skin weights. 353 | deformer_inf_jnts (list): List of influenced joint names from the deformer. 354 | mesh_inf_jnts (list): List of influenced joint names from the mesh. 355 | 356 | """ 357 | 358 | def __init__(self, deformer=None, mesh=None): 359 | getData.__init__(self) 360 | self.deformer = deformer 361 | self.mesh = mesh 362 | self.meshCluster = None 363 | self.vertNumber = [] 364 | self.hold_skin_value = [] 365 | self.deformer_inf_jnts = getData().get_influnced_joints(self.deformer) 366 | self.Mesh_inf_jnts = getData().get_influnced_joints(self.mesh) 367 | self.NewjntNam = None 368 | self.hold_jntSuffix = '_hold_jnt' 369 | self.dupMesh = None 370 | 371 | def deformer_skin_convert(self): 372 | """ 373 | Convert skin weights from the deformer to the mesh. 374 | 375 | Use For Curve to Skin 376 | 377 | """ 378 | # get mesh skin cluster 379 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 380 | 381 | # check if there is a cluster else create a new one 382 | if self.meshCluster == None: 383 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 384 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 385 | 386 | self.meshCluster = pm.skinCluster( 387 | self.mesh + self.hold_jntSuffix, self.mesh) 388 | cmds.select(cl=1) 389 | 390 | # get influnced joints of the mesh 391 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 392 | 393 | # get unlocked joint to transfer deformer weight 394 | unlockJnt = getData().getUnlockedJnt(mesh_joints) 395 | 396 | # lock all other weights except the first unlocked weight 397 | pm.setAttr(unlockJnt[0] + ".liw", 1) 398 | 399 | # get effected verticies 400 | self.vertNumber = getData().effectedVertNumber(self.meshCluster, unlockJnt) 401 | 402 | # save hold joint's weight 403 | for fdf in self.vertNumber: 404 | JntVal = pm.skinPercent( 405 | str(self.meshCluster), 406 | self.mesh + ".vtx[" + fdf + "]", 407 | transform=unlockJnt[0], 408 | query=True, 409 | ) 410 | self.hold_skin_value.append(JntVal) 411 | 412 | # Add other joints to skin cluster 413 | for gfs in self.deformer_inf_jnts: 414 | pm.skinCluster(self.meshCluster, edit=True, ai=gfs, lw=1) 415 | 416 | # Create wire deformer 417 | wireDfm = pm.wire( 418 | self.mesh, 419 | w=self.deformer, 420 | gw=False, 421 | en=1.000000, 422 | ce=0.000000, 423 | li=0.000000, 424 | dds=[(0, 1000)], 425 | )[0] 426 | pm.setAttr(wireDfm.rotation, 0) 427 | 428 | for xx in self.deformer_inf_jnts: 429 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 430 | WeightbyPercent = getData().WeightByOnePercentage( 431 | Fineldistance, self.hold_skin_value 432 | ) 433 | 434 | # apply skin weight 435 | cmds.setAttr(unlockJnt[0] + ".liw", 0) 436 | for R in self.vertNumber: 437 | if WeightbyPercent[self.vertNumber.index(R)] != 0.0: 438 | pm.skinPercent( 439 | self.meshCluster, 440 | self.mesh + ".vtx[" + R + "]", 441 | tv=(xx, WeightbyPercent[self.vertNumber.index(R)]), 442 | ) 443 | 444 | for fv in self.deformer_inf_jnts: 445 | pm.setAttr(fv + ".liw", 0) 446 | 447 | pm.skinCluster(self.meshCluster, e=True, ri=unlockJnt[0]) 448 | 449 | # cleanup 450 | if self.meshCluster == []: 451 | pm.delete(unlockJnt[0]) 452 | 453 | pm.disconnectAttr((cmds.listRelatives(self.deformer, shapes=True)[ 454 | 0])+".worldSpace[0]", wireDfm+".deformedWire[0]") 455 | pm.delete(wireDfm) 456 | pm.delete(self.deformer + "BaseWire") 457 | 458 | def rest_deformer_skin_convert(self): 459 | """ 460 | Restore the original skin weights on the mesh after deformer conversion. 461 | 462 | Use for Wire, Wrap, delta Mesh and Lattice 463 | 464 | """ 465 | 466 | # to check type of deformer and set wire rotation 1 467 | getData().deformerType(self.mesh) 468 | 469 | meshSkinClust = [getData(object=self.mesh).get_skinCluster()] 470 | 471 | deformerSkinClust = getData(object=self.deformer).get_skinCluster() 472 | 473 | if not deformerSkinClust: # error if no skin 474 | pm.error("<<<<<(No SKIN found on deformer)>>>>>") 475 | 476 | if deformerSkinClust in meshSkinClust: # reomve if same skincluster in mesh 477 | meshSkinClust.remove(deformerSkinClust) 478 | 479 | # check if there is a cluster else create a new one 480 | if self.meshCluster == None: 481 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 482 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 483 | 484 | self.meshCluster = pm.skinCluster( 485 | self.mesh + self.hold_jntSuffix, self.mesh) 486 | cmds.select(cl=1) 487 | 488 | # get effected verticies 489 | self.vertNumber = [str(i) for i in range( 490 | cmds.polyEvaluate(self.mesh, v=True))] 491 | 492 | # Add other joints to skin cluster 493 | pm.skinCluster(self.meshCluster, 494 | ai=self.deformer_inf_jnts, edit=True, lw=1, wt=0) 495 | 496 | for xx in self.deformer_inf_jnts: 497 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 498 | 499 | # skin apply 500 | for R in self.vertNumber: 501 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 502 | pm.skinPercent( 503 | self.meshCluster, 504 | self.mesh + ".vtx[" + R + "]", 505 | tv=(xx, Fineldistance[self.vertNumber.index(R)]), 506 | ) 507 | 508 | for fv in self.deformer_inf_jnts: 509 | pm.setAttr(fv + ".liw", 0) 510 | 511 | def SoftSelectionToConvert(self): 512 | sel = cmds.ls(sl=True) 513 | 514 | cmds.select(d=1) 515 | 516 | bbx = cmds.xform(sel, q=True, bb=True, ws=True) 517 | 518 | positon = ( 519 | ((bbx[0] + bbx[3]) / 2.0), 520 | ((bbx[1] + bbx[4]) / 2.0), 521 | ((bbx[2] + bbx[5]) / 2.0), 522 | ) 523 | 524 | self.mesh = sel[0].split(".")[0] 525 | 526 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 527 | 528 | # check if there is a cluster else create a new one 529 | if self.meshCluster == None: 530 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 531 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 532 | 533 | self.meshCluster = pm.skinCluster( 534 | self.mesh + self.hold_jntSuffix, self.mesh) 535 | cmds.select(cl=1) 536 | 537 | # get influnced joints of the mesh 538 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 539 | 540 | # get unlocked joint to transfer deformer weight 541 | unlockJnt = getData().getUnlockedJnt(mesh_joints) 542 | 543 | self.vertNumber = getData().effectedVertNumber(self.meshCluster, unlockJnt) 544 | 545 | # Add new joints to skin cluster 546 | if cmds.objExists(self.mesh + "_001_Jnt") == False: 547 | self.NewjntNam = cmds.joint(n=self.mesh + "_001_Jnt", p=positon) 548 | cmds.skinCluster(self.mesh, edit=True, 549 | ai=self.NewjntNam, lw=1, wt=0) 550 | else: 551 | self.NewjntNam = getData().NewJnt(positon, self.mesh) 552 | cmds.skinCluster(self.mesh, edit=True, 553 | ai=self.NewjntNam, lw=1, wt=0) 554 | 555 | cmds.select(sel) 556 | for i in utils().softSelection(): 557 | cmds.select(d=1) 558 | 559 | pm.skinPercent( 560 | self.meshCluster, 561 | self.mesh + ".vtx[" + str(i[0]) + "]", 562 | tv=(self.NewjntNam, i[1]), 563 | ) 564 | 565 | def ClusterConvert(self): 566 | 567 | positon = cmds.getAttr(self.deformer+'.origin')[0] 568 | cmds.select(d=True) 569 | 570 | clust = getData(object=self.mesh).get_skinCluster() 571 | 572 | if clust == None: 573 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 574 | pm.joint(n=self.mesh + self.hold_jntSuffix) 575 | 576 | pm.skinCluster(self.mesh + self.hold_jntSuffix, self.mesh) 577 | 578 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 579 | # pm.setAttr(mesh_joints[0]+'.liw', 1) 580 | 581 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 582 | 583 | # get effected verticies 584 | self.vertNumber = getData().effectedVertNumber( 585 | self.meshCluster, self.mesh + self.hold_jntSuffix) 586 | 587 | Fineldistance = getData().VertDistance( 588 | self.mesh, self.vertNumber, self.deformer, moveType="") 589 | 590 | if pm.objExists(self.mesh + "_001_Jnt") == False: 591 | self.NewjntNam = cmds.joint(n=self.mesh + "_001_Jnt", p=positon) 592 | cmds.skinCluster(self.mesh, edit=True, 593 | ai=self.NewjntNam, lw=1, wt=0) 594 | else: 595 | self.NewjntNam = getData().NewJnt(positon, self.mesh) 596 | cmds.skinCluster(self.mesh, edit=True, 597 | ai=self.NewjntNam, lw=1, wt=0) 598 | 599 | # skin apply 600 | for R in self.vertNumber: 601 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 602 | pm.skinPercent( 603 | self.meshCluster, 604 | self.mesh + ".vtx[" + R + "]", 605 | tv=(self.NewjntNam, 606 | Fineldistance[self.vertNumber.index(R)]), 607 | ) 608 | 609 | def blendShapeConvert(self): 610 | 611 | self.deformer = getData().BlendShape(self.mesh) 612 | 613 | WeightNam = pm.listAttr(self.deformer[0] + '.w', m=True) 614 | 615 | clust = getData(object=self.mesh).get_skinCluster() 616 | 617 | if clust == None: 618 | cmds.select(d=1) 619 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 620 | pm.joint(n=self.mesh + self.hold_jntSuffix) 621 | 622 | pm.skinCluster(self.mesh + self.hold_jntSuffix, self.mesh) 623 | 624 | pm.setAttr(self.deformer[0] + '.' + WeightNam[0], 1) 625 | 626 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 627 | 628 | self.vertNumber = getData().effectedVertNumber( 629 | self.meshCluster, self.mesh + self.hold_jntSuffix) 630 | 631 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, 632 | self.deformer, moveType="", BS=True, WeightName=WeightNam) 633 | 634 | if pm.objExists(self.mesh + "_001_Jnt") == False: 635 | self.NewjntNam = cmds.joint(n=self.mesh + "_001_Jnt", p=(0, 0, 0)) 636 | cmds.skinCluster(self.mesh, edit=True, 637 | ai=self.NewjntNam, lw=1, wt=0) 638 | else: 639 | self.NewjntNam = getData().NewJnt((0, 0, 0), self.mesh) 640 | cmds.skinCluster(self.mesh, edit=True, 641 | ai=self.NewjntNam, lw=1, wt=0) 642 | 643 | # skin apply 644 | for R in self.vertNumber: 645 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 646 | pm.skinPercent( 647 | self.meshCluster, 648 | self.mesh + ".vtx[" + R + "]", 649 | tv=(self.NewjntNam, 650 | Fineldistance[self.vertNumber.index(R)]), 651 | ) 652 | 653 | def deltaMush_skin_convert(self): 654 | """ 655 | Restore the original skin weights on the mesh after deformer conversion. 656 | 657 | Use for Wire, Wrap, delta Mesh and Lattice 658 | 659 | """ 660 | # print (self.Mesh_inf_jnts) 661 | # getData().check_connections(self.Mesh_inf_jnts) 662 | 663 | self.dupMesh = cmds.duplicate(self.mesh, n=self.mesh+"_Test")[0] 664 | 665 | meshSkinClust = [getData(object=self.mesh).get_skinCluster()] 666 | 667 | if not meshSkinClust: # error if no skin 668 | pm.error("<<<<<(No SKIN found on mesh)>>>>>") 669 | 670 | # check if there is a cluster else create a new one 671 | if self.meshCluster == None: 672 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 673 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 674 | 675 | pm.skinCluster( 676 | meshSkinClust[0], ai=self.mesh + self.hold_jntSuffix, edit=True, lw=0, wt=0) 677 | 678 | # get effected verticies 679 | self.vertNumber = [str(i) for i in range( 680 | cmds.polyEvaluate(self.mesh, v=True))] 681 | 682 | # Add all joints to skin cluster with dupMesh 683 | self.meshCluster = pm.skinCluster(self.Mesh_inf_jnts, self.dupMesh) 684 | cmds.select(cl=1) 685 | pm.skinCluster(self.meshCluster, ai=self.mesh + 686 | self.hold_jntSuffix, edit=True, lw=0, wt=0) 687 | 688 | for xx in self.Mesh_inf_jnts: 689 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 690 | 691 | # skin apply 692 | for R in self.vertNumber: 693 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 694 | pm.skinPercent( 695 | self.meshCluster, 696 | self.dupMesh + ".vtx[" + R + "]", 697 | tv=(xx, Fineldistance[self.vertNumber.index(R)]), 698 | ) 699 | 700 | for fv in self.Mesh_inf_jnts: 701 | pm.setAttr(fv + ".liw", 0) 702 | 703 | # copyWeight from dup mesh to main mesh 704 | cmds.connectAttr(self.meshCluster + ".weightList", 705 | meshSkinClust[0].name() + ".weightList",) 706 | cmds.disconnectAttr(self.meshCluster + ".weightList", 707 | meshSkinClust[0].name() + ".weightList",) 708 | cmds.delete(self.dupMesh, self.mesh + self.hold_jntSuffix) 709 | 710 | # TODO "error, 'only one joint' " softseletion convert, when other joint are unlocked, maybe it 711 | # should give error 712 | 713 | # deltaMush working with heirarchy, but there should not be any key (add error) 714 | -------------------------------------------------------------------------------- /old_files/skintools_v1.py: -------------------------------------------------------------------------------- 1 | import maya.OpenMaya as om, pymel.core as pm, maya.cmds as cmds 2 | import time, math, sys 3 | import maya.cmds as cmds 4 | import pymel.core as pm 5 | import importlib 6 | import pymel.core as pm 7 | import maya.cmds as cmds 8 | import pymel.core as pm 9 | import sys 10 | import importlib as imp 11 | """ 12 | 13 | ui 14 | query definations - selection check error 15 | find data 16 | create curve from transforms 17 | one defination for all deformer----* 18 | skin cluster utils 19 | export/import- skin/deformers 20 | copy skin 21 | vertex weight slider 22 | mirror deformer weight 23 | """ 24 | 25 | 26 | class utils: 27 | def __init__(self, object=None): 28 | self.obj = object 29 | 30 | # one defination for all 31 | def WhichDeformerButton(self, ddeformer): 32 | if ddeformer == "Wire": 33 | print("Converting wire deformer to skin") 34 | 35 | if ddeformer == "Lattice": 36 | print("Converting Lattice deformer to skin") 37 | 38 | if ddeformer == "Wrap": 39 | print("Converting Wrap deformer to skin") 40 | 41 | if ddeformer == "Cluster": 42 | print("Converting Cluster deformer to skin") 43 | 44 | if ddeformer == "SoftSelection": 45 | print("Converting SoftSelection deformer to skin") 46 | 47 | if ddeformer == "DeltaMesh": 48 | print("Converting DeltaMesh deformer to skin") 49 | 50 | def CreateCrv(self): 51 | crv = cmds.curve(p=[cmds.xform(d, t=1, q=1, ws=1) for d in cmds.ls(sl=1)]) 52 | cmds.setAttr(crv+".dispCV", 1) 53 | #cmds.setAttr("curveShape1.overrideEnabled", 1) 54 | #cmds.setAttr("curveShape1.overrideColor", 5) 55 | # TODO should we really add this(create curve) if yes how ? 56 | 57 | def softSelection(self): 58 | selection = om.MSelectionList() 59 | softSelection = om.MRichSelection() 60 | om.MGlobal.getRichSelection(softSelection) 61 | softSelection.getSelection(selection) 62 | 63 | dagPath = om.MDagPath() 64 | component = om.MObject() 65 | 66 | iter = om.MItSelectionList(selection, om.MFn.kMeshVertComponent) 67 | elements = [] 68 | while not iter.isDone(): 69 | iter.getDagPath(dagPath, component) 70 | dagPath.pop() 71 | fnComp = om.MFnSingleIndexedComponent(component) 72 | for i in range(fnComp.elementCount()): 73 | elements.append([fnComp.element(i), fnComp.weight(i).influence()]) 74 | iter.next() 75 | return elements 76 | 77 | 78 | class getData: 79 | """ 80 | A class for extracting information and performing calculations related to deformations. 81 | """ 82 | 83 | def __init__(self, object=None): 84 | self.obj = object 85 | 86 | def get_skinCluster(self): 87 | """ 88 | Get the skinCluster associated with the object. 89 | 90 | Returns: 91 | skinCluster (str or None): The name of the skinCluster or None if not found. 92 | 93 | """ 94 | pyObj = pm.PyNode(self.obj) 95 | try: 96 | self.skn = pm.ls(pm.listHistory(pyObj), typ="skinCluster")[0] 97 | return self.skn 98 | 99 | except: 100 | return None 101 | 102 | def get_influnced_joints(self, skin_node=None): 103 | """ 104 | Get the list of influenced joints by a given skinCluster. 105 | 106 | Args: 107 | skin_node (str): The name of the skinCluster. 108 | 109 | Returns: 110 | influences (list or None): A list of influenced joint names or None if not found. 111 | 112 | """ 113 | try: 114 | self.influences = pm.skinCluster(skin_node, inf=True, q=True) 115 | return self.influences 116 | 117 | except: 118 | # pm.error('No skinCluster found!') 119 | pass 120 | 121 | def solvVert(self, vertcnt): 122 | """ 123 | Extract vertex numbers from vertex count strings. 124 | 125 | Args: 126 | vertcnt (list): List of vertex count strings. 127 | 128 | Returns: 129 | totalCounts (list): List of extracted vertex numbers as strings. 130 | 131 | """ 132 | totalCounts = [] 133 | 134 | for vert in vertcnt: 135 | split01 = vert.split("[") 136 | split02 = split01[-1].split("]") 137 | start = int(split02[0]) 138 | 139 | totalCounts.append(str(start)) 140 | 141 | return totalCounts 142 | 143 | def effectedVertNumber(self, meshClust, unlockJt): 144 | """ 145 | Calculate the affected vertex numbers when a joint is unlocked in a skinCluster. 146 | 147 | Args: 148 | meshClust (str): The name of the skinCluster. 149 | unlockJt (str): The name of the joint to be unlocked. 150 | 151 | Returns: 152 | vertNumb (list): List of affected vertex numbers as strings. 153 | 154 | """ 155 | vertNumb = [] 156 | pm.select(cl=1) 157 | pm.skinCluster(meshClust, e=True, siv=unlockJt) 158 | effectdVrt0 = cmds.ls(sl=True, fl=1) 159 | vertNumb = getData().solvVert(effectdVrt0) 160 | cmds.select(d=1) 161 | 162 | return vertNumb 163 | 164 | def getUnlockedJnt(self, mesh_joinds): 165 | """ 166 | Find and return joints that are unlocked among a list of joints. 167 | 168 | Args: 169 | mesh_joints (list): List of joint names to check. 170 | 171 | Returns: 172 | unlockJnd (list): List of unlocked joint names. 173 | 174 | Raises: 175 | pm.error: If no joint is unlocked or if more than one joint is unlocked. 176 | 177 | """ 178 | unlockJnd = [] 179 | for n in mesh_joinds: 180 | findlock = pm.getAttr(n + ".liw") 181 | if findlock == False: 182 | unlockJnd.append(n) 183 | 184 | if unlockJnd == []: 185 | pm.error("Please unlock one joint for distributing the weight") 186 | 187 | if len(unlockJnd) > 1: 188 | pm.error("Only one joint should be unlocked") 189 | 190 | return unlockJnd 191 | 192 | # ---------------------------------------------------Distance between two vertex 193 | 194 | def VertDistance(self, meshNam, VertNumList, moverNam, moveType = ".rotatePivot"): 195 | """ 196 | Calculate the distances between two sets of vertices on a mesh. 197 | 198 | Args: 199 | mesh_name (str): The name of the mesh. 200 | vert_num_list (list): List of vertex numbers as strings. 201 | mover_name (str): The name of the mover object. 202 | 203 | Returns: 204 | Distance (list): List of distances between vertices. 205 | 206 | """ 207 | old_PoseVert = [] 208 | New_PoseVert = [] 209 | Distance = [] 210 | 211 | for xyz in [0, 1, 2]: 212 | set_01Z = [] 213 | 214 | for d in VertNumList: 215 | Attr = pm.xform(meshNam + ".vtx[" + d + "]", q=True, ws=True, t=True)[ 216 | xyz 217 | ] 218 | 219 | set_01Z.append((Attr)) 220 | pm.select(d=True) 221 | 222 | old_PoseVert.append(set_01Z) 223 | 224 | pm.move(1, moverNam + moveType, y=True, r=True) 225 | 226 | for xyz in [0, 1, 2]: 227 | set_02Z = [] 228 | 229 | for b in VertNumList: 230 | Attrs = pm.xform(meshNam + ".vtx[" + b + "]", q=True, ws=True, t=True)[ 231 | xyz 232 | ] 233 | 234 | set_02Z.append((Attrs)) 235 | pm.select(d=True) 236 | 237 | New_PoseVert.append(set_02Z) 238 | 239 | pm.move(-1, moverNam + moveType, y=True, r=True) 240 | 241 | for o in range(len(VertNumList)): 242 | x1, y1, z1 = ( 243 | float(old_PoseVert[0][o]), 244 | float(old_PoseVert[1][o]), 245 | float(old_PoseVert[2][o]), 246 | ) 247 | x2, y2, z2 = ( 248 | float(New_PoseVert[0][o]), 249 | float(New_PoseVert[1][o]), 250 | float(New_PoseVert[2][o]), 251 | ) 252 | 253 | Distance.append( 254 | math.sqrt( 255 | ((x1 - x2) * (x1 - x2)) 256 | + ((y1 - y2) * (y1 - y2)) 257 | + ((z1 - z2) * (z1 - z2)) 258 | ) 259 | ) 260 | 261 | return Distance 262 | 263 | # ---------------------------------------------------percentage_find 264 | 265 | def WeightByOnePercentage(self, distance, hold_skin): 266 | """ 267 | Calculate weight values based on distances and skinCluster weights. 268 | 269 | Args: 270 | distance (list): List of distances between vertices. 271 | hold_skin (list): List of skinCluster weights. 272 | 273 | Returns: 274 | percentage (list): List of weight values. 275 | 276 | """ 277 | percentage = [] 278 | 279 | for nnn in range(len(hold_skin)): 280 | Onepercentage = (hold_skin[nnn] / 1.0) * distance[nnn] 281 | percentage.append(Onepercentage) 282 | 283 | return percentage 284 | 285 | # --------------------------------------------------- check deformer Type 286 | def deformerType(self, Name): 287 | """ 288 | Identify and return the type of deformer applied to an object. 289 | 290 | Args: 291 | name (str): The name of the object. 292 | 293 | Returns: 294 | deformer_type (str): The type of deformer (e.g., 'wire', 'lattice', 'cluster', 'wrap', 'blendShape'). 295 | 296 | """ 297 | nodes = [] 298 | 299 | for dfm in cmds.listHistory(Name): 300 | if cmds.nodeType(dfm) == "wire": 301 | pm.setAttr(dfm + ".rotation", 0.0) 302 | nodes.append("wire") 303 | if cmds.nodeType(dfm) == "lattice": 304 | nodes.append("lattice") 305 | if cmds.nodeType(dfm) == "cluster": 306 | nodes.append("cluster") 307 | if cmds.nodeType(dfm) == "wrap": 308 | nodes.append("wrap") 309 | if cmds.nodeType(dfm) == "blendShape": 310 | nodes.append("blendShape") 311 | 312 | return nodes[0] 313 | 314 | 315 | def NewJnt(self, positonN, MeshNam): 316 | cmds.select(d=True) 317 | objList = cmds.ls(MeshNam + "_*_Jnt") 318 | number = [int(i.split("_")[1]) for i in objList] 319 | 320 | nList = [] 321 | for i in range(1, len(number)+2): 322 | if i not in number: 323 | nList.append(i) 324 | 325 | jntt = cmds.joint(n= MeshNam + "_" + str(nList[0]).zfill(3) + "_Jnt", p=positonN) 326 | cmds.select(d=True) 327 | return jntt 328 | 329 | 330 | class deformerConvert(getData): 331 | """ 332 | Main class for converting deformers to skincluster. 333 | 334 | Args: 335 | deformer (str, optional): The name of the deformer to be converted. 336 | mesh (str, optional): The name of the mesh to be processed. 337 | 338 | Attributes: 339 | deformer (str): The name of the deformer being converted. 340 | mesh (str): The name of the mesh being processed. 341 | hold_joint (str or None): The name of the hold joint created or None. 342 | meshCluster (str or None): The name of the mesh's skinCluster or None. 343 | vertNumber (list): List of vertex numbers as strings. 344 | hold_skin_value (list): List of hold joint's skin weights. 345 | inf_jnts (list): List of influenced joint names from the deformer. 346 | 347 | """ 348 | 349 | def __init__(self, deformer=None, mesh=None): 350 | getData.__init__(self) 351 | self.deformer = deformer 352 | self.mesh = mesh 353 | self.hold_joint = None 354 | self.meshCluster = None 355 | self.vertNumber = [] 356 | self.hold_skin_value = [] 357 | self.inf_jnts = getData().get_influnced_joints(self.deformer) 358 | self.NewjntNam = None 359 | self.hold_jnt = '_hold_jnt' 360 | 361 | def deformer_skin_convert(self): 362 | """ 363 | Convert skin weights from the deformer to the mesh. 364 | 365 | Use For Curve to Skin 366 | 367 | """ 368 | # get mesh skin cluster 369 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 370 | 371 | # check if there is a cluster else create a new one 372 | if self.meshCluster == None: 373 | if pm.objExists(self.mesh + self.hold_jnt) == False: 374 | self.hold_joint = pm.createNode("joint", n=self.mesh + self.hold_jnt) 375 | 376 | self.meshCluster = pm.skinCluster(self.hold_joint, self.mesh) 377 | cmds.select(cl=1) 378 | 379 | # get influnced joints of the mesh 380 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 381 | 382 | # get unlocked joint to transfer deformer weight 383 | unlockJnt = getData().getUnlockedJnt(mesh_joints) 384 | 385 | # lock all other weights except the first unlocked weight 386 | pm.setAttr(unlockJnt[0] + ".liw", 1) 387 | 388 | # get effected verticies 389 | self.vertNumber = getData().effectedVertNumber(self.meshCluster, unlockJnt) 390 | 391 | # save hold joint's weight 392 | for fdf in self.vertNumber: 393 | JntVal = pm.skinPercent( 394 | str(self.meshCluster), 395 | self.mesh + ".vtx[" + fdf + "]", 396 | transform=unlockJnt[0], 397 | query=True, 398 | ) 399 | self.hold_skin_value.append(JntVal) 400 | 401 | # Add other joints to skin cluster 402 | for gfs in self.inf_jnts: 403 | pm.skinCluster(self.meshCluster, edit=True, ai=gfs, lw=1) 404 | 405 | # Create wire deformer 406 | wireDfm = pm.wire( 407 | self.mesh, 408 | w=self.deformer, 409 | gw=False, 410 | en=1.000000, 411 | ce=0.000000, 412 | li=0.000000, 413 | dds=[(0, 1000)], 414 | )[0] 415 | pm.setAttr(wireDfm.rotation, 0) 416 | 417 | for xx in self.inf_jnts: 418 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 419 | WeightbyPercent = getData().WeightByOnePercentage( 420 | Fineldistance, self.hold_skin_value 421 | ) 422 | 423 | # apply skin weight 424 | cmds.setAttr(unlockJnt[0] + ".liw", 0) 425 | for R in self.vertNumber: 426 | if WeightbyPercent[self.vertNumber.index(R)] != 0.0: 427 | pm.skinPercent( 428 | self.meshCluster, 429 | self.mesh + ".vtx[" + R + "]", 430 | tv=(xx, WeightbyPercent[self.vertNumber.index(R)]), 431 | ) 432 | 433 | for fv in self.inf_jnts: 434 | pm.setAttr(fv + ".liw", 0) 435 | 436 | pm.skinCluster(self.meshCluster, e=True, ri=unlockJnt[0]) 437 | 438 | # cleanup 439 | if self.meshCluster == []: 440 | pm.delete(unlockJnt[0]) 441 | 442 | pm.disconnectAttr((cmds.listRelatives(self.deformer, shapes=True)[0])+".worldSpace[0]", wireDfm+".deformedWire[0]") 443 | pm.delete(wireDfm) 444 | pm.delete(self.deformer + "BaseWire") 445 | 446 | def rest_deformer_skin_convert(self): 447 | """ 448 | Restore the original skin weights on the mesh after deformer conversion. 449 | 450 | Use for Wire, Wrap, delta Mesh and Lattice 451 | 452 | """ 453 | 454 | deformerTyp = getData().deformerType( 455 | self.mesh 456 | ) # to check type of deformer and set wire rotation 1 457 | 458 | meshSkinClust = [getData(object=self.mesh).get_skinCluster()] 459 | 460 | deformerSkinClust = getData(object=self.deformer).get_skinCluster() 461 | 462 | if not deformerSkinClust: # error if no skin 463 | pm.error("<<<<<(No SKIN found on deformer)>>>>>") 464 | 465 | if deformerSkinClust in meshSkinClust: # reomve if same skincluster in mesh 466 | meshSkinClust.remove(deformerSkinClust) 467 | 468 | # check if there is a cluster else create a new one 469 | if self.meshCluster == None: 470 | if pm.objExists(self.mesh + self.hold_jnt) == False: 471 | self.hold_joint = pm.createNode("joint", n=self.mesh + self.hold_jnt) 472 | 473 | self.meshCluster = pm.skinCluster(self.hold_joint, self.mesh) 474 | cmds.select(cl=1) 475 | 476 | # get influnced joints of the mesh 477 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 478 | 479 | # get effected verticies 480 | self.vertNumber = [str(i) for i in range(cmds.polyEvaluate(self.mesh, v=True))] 481 | 482 | # Add other joints to skin cluster 483 | 484 | pm.skinCluster(self.meshCluster, ai=self.inf_jnts, edit=True, lw=1, wt=0) 485 | 486 | for xx in self.inf_jnts: 487 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 488 | 489 | # skin apply 490 | for R in self.vertNumber: 491 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 492 | pm.skinPercent( 493 | self.meshCluster, 494 | self.mesh + ".vtx[" + R + "]", 495 | tv=(xx, Fineldistance[self.vertNumber.index(R)]), 496 | ) 497 | 498 | for fv in self.inf_jnts: 499 | pm.setAttr(fv + ".liw", 0) 500 | 501 | # ---------------------------------------------------delete_Unwanted_Things 502 | 503 | def SoftSelectionToConvert(self): 504 | sel = cmds.ls(sl=True) 505 | 506 | cmds.select(d=1) 507 | 508 | bbx = cmds.xform(sel, q=True, bb=True, ws=True) 509 | 510 | positon = ( 511 | ((bbx[0] + bbx[3]) / 2.0), 512 | ((bbx[1] + bbx[4]) / 2.0), 513 | ((bbx[2] + bbx[5]) / 2.0), 514 | ) 515 | 516 | self.mesh = sel[0].split(".")[0] 517 | 518 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 519 | 520 | # check if there is a cluster else create a new one 521 | if self.meshCluster == None: 522 | if pm.objExists(self.mesh + self.hold_jnt) == False: 523 | self.hold_joint = pm.createNode("joint", n=self.mesh + self.hold_jnt) 524 | 525 | self.meshCluster = pm.skinCluster(self.hold_joint, self.mesh) 526 | cmds.select(cl=1) 527 | 528 | # get influnced joints of the mesh 529 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 530 | 531 | # get unlocked joint to transfer deformer weight 532 | unlockJnt = getData().getUnlockedJnt(mesh_joints) 533 | 534 | self.vertNumber = getData().effectedVertNumber(self.meshCluster, unlockJnt) 535 | 536 | # Add new joints to skin cluster 537 | 538 | if cmds.objExists(self.mesh + "_001_Jnt") == False: 539 | self.NewjntNam = cmds.joint(n=self.mesh + "_001_Jnt", p=positon) 540 | cmds.skinCluster(self.mesh, edit=True, ai=self.NewjntNam, lw=1, wt=0) 541 | else: 542 | self.NewjntNam = getData().NewJnt(positon, self.mesh) 543 | cmds.skinCluster(self.mesh, edit=True, ai=self.NewjntNam, lw=1, wt=0) 544 | 545 | cmds.select(sel) 546 | for i in utils().softSelection(): 547 | cmds.select(d=1) 548 | 549 | pm.skinPercent( 550 | self.meshCluster, 551 | self.mesh + ".vtx[" + str(i[0]) + "]", 552 | tv=(self.NewjntNam, i[1]), 553 | ) 554 | 555 | 556 | def ClusterConvert(self): 557 | 558 | positon = cmds.getAttr(self.deformer+'.origin')[0] 559 | cmds.select(d =True) 560 | 561 | clust = getData(object=self.mesh).get_skinCluster() 562 | 563 | if clust==None: 564 | if pm.objExists(self.mesh + self.hold_jnt) == False: 565 | pm.joint(n = self.mesh + self.hold_jnt) 566 | 567 | pm.skinCluster(self.mesh + self.hold_jnt, self.mesh) 568 | 569 | 570 | mesh_joints = pm.skinCluster(self.mesh, inf = True, q = True) 571 | #pm.setAttr(mesh_joints[0]+'.liw', 1) 572 | 573 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 574 | 575 | # get effected verticies 576 | self.vertNumber = getData().effectedVertNumber(self.meshCluster, self.mesh + self.hold_jnt) 577 | 578 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, self.deformer, moveType = "") 579 | 580 | 581 | if pm.objExists(self.mesh + "_001_Jnt") == False: 582 | self.NewjntNam = cmds.joint(n = self.mesh + "_001_Jnt", p = positon) 583 | cmds.skinCluster(self.mesh, edit=True, ai=self.NewjntNam, lw=1, wt=0) 584 | else: 585 | self.NewjntNam = getData().NewJnt(positon, self.mesh) 586 | cmds.skinCluster(self.mesh, edit=True, ai=self.NewjntNam, lw=1, wt=0) 587 | 588 | # skin apply 589 | for R in self.vertNumber: 590 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 591 | pm.skinPercent( 592 | self.meshCluster, 593 | self.mesh + ".vtx[" + R + "]", 594 | tv=(self.NewjntNam, Fineldistance[self.vertNumber.index(R)]), 595 | ) 596 | 597 | 598 | 599 | 600 | # Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 601 | 602 | # TODO Cluster and Blendshape Function need to be added 603 | # TODO curve script not working with unlock a joint(solve it) 604 | # TODO get_influnced_joints not working for Wire1 605 | # just to remind myself:- self.variable bnane h har jgha 606 | # TODO you can call function with self.functionName also, but it should be inside the same class 607 | # TODO is there any alternate ?, ask to sid for "NewJnt" function. 608 | 609 | ######################################################################################################### 610 | # window 611 | win_name = "vn_skin_tools" 612 | win_title = "Skin Tools" 613 | win_size = (330, 300) 614 | if pm.window(win_name, q=1, exists=True): 615 | pm.deleteUI(win_name, window=True) 616 | 617 | """ 618 | if pm.windowPref(win_name,q=1 ,exists=True ): 619 | pm.windowPref(win_name, r=0 ) 620 | """ 621 | pm.window( 622 | win_name, 623 | title=win_title, 624 | widthHeight=win_size, 625 | sizeable=False, 626 | bgc=[(0.2), (0.2), (0.2)], 627 | ) 628 | 629 | Tab = pm.tabLayout("Tabs", p=win_name, tc=0, stb=1, snt=1) 630 | 631 | deformer_form = pm.formLayout("Converter", parent="Tabs") 632 | skin_utils_form = pm.formLayout("Import/Export", parent="Tabs") 633 | output_win_frame = pm.formLayout("MirrorWeights", parent="Tabs") 634 | 635 | 636 | radio_layout = pm.rowColumnLayout(nc=2, p=deformer_form, cal=[2, "left"], h=55) 637 | radio_coll = pm.radioCollection(parent=radio_layout) 638 | crv_to_skn_btn = pm.radioButton( 639 | "crv_skn_rb", l="Curve To Skin", p=radio_layout, sl=1, cc="crv_skn_cc()" 640 | ) 641 | softsel_to_skn = pm.radioButton( 642 | "softsel_skn_rb", l="Soft Selection To Skin", p=radio_layout, cc="softSel_skn_cc()" 643 | ) 644 | cluster_to_skn = pm.radioButton( 645 | "cls_skn_rb", l="Cluster To Skin", p=radio_layout, cc="cl_skn_cc()" 646 | ) 647 | df_to_skn_btn = pm.radioButton( 648 | "restdf_skn_rb", l="Wire/Wrap/Lattice/DeltaMush", p=radio_layout, cc="df_skn_cc()" 649 | ) 650 | blendshape_to_skn = pm.radioButton( 651 | "bs_skn_rb", l="Blendshape To Skin", p=radio_layout) 652 | 653 | informatipn_txt_f = pm.textField( 654 | "info_txtf", 655 | w=180, 656 | h=25, 657 | p=deformer_form, 658 | en=0, 659 | pht="Add a Skinned Curve and Mesh", 660 | nbg=1, 661 | ) 662 | 663 | mesh_textfield = pm.textField( 664 | "mesh_field", w=180, h=35, pht="Add Mesh", p=deformer_form 665 | ) 666 | deformer_textfield = pm.textField( 667 | "df_field", w=180, h=35, pht="Add Skinned Curve", p=deformer_form 668 | ) 669 | 670 | override_checkbox = pm.checkBox( 671 | label="Override Skin Cluster", align="left", p=deformer_form 672 | ) 673 | unlocedvtx_checkbox = pm.checkBox( 674 | label="Unlocked Influneces Only", align="center", p=deformer_form 675 | ) 676 | 677 | 678 | add_mesh_btn = pm.button( 679 | "mesh_btn", l="Select Mesh", p=deformer_form, w=120, h=34, c="mesh_add()" 680 | ) 681 | add_df_btn = pm.button( 682 | "df_btn", l="Select Deformer", p=deformer_form, w=120, h=34, c="deformer_add()" 683 | ) 684 | convert_btn = pm.iconTextButton( 685 | "cvt_btn", 686 | style="iconAndTextHorizontal", 687 | image1="polyColorSetEditor.png", 688 | label="Convert to Skin", 689 | p=deformer_form, 690 | w=130, 691 | h=40, 692 | bgc=[(0.23), (0.23), (0.253)], 693 | c="convert_to_skin()", 694 | ) 695 | 696 | pm.formLayout( 697 | deformer_form, 698 | e=1, 699 | attachForm=[ 700 | (radio_layout, "top", 10), 701 | (informatipn_txt_f, "top", 67), 702 | (mesh_textfield, "top", 97), 703 | (deformer_textfield, "top", 135), 704 | (add_mesh_btn, "top", 98), 705 | (add_df_btn, "top", 136), 706 | (override_checkbox, "top", 180), 707 | (unlocedvtx_checkbox, "top", 200), 708 | (convert_btn, "top", 228), 709 | (informatipn_txt_f, "left", 10), 710 | (radio_layout, "left", 10), 711 | (mesh_textfield, "left", 10), 712 | (deformer_textfield, "left", 10), 713 | (override_checkbox, "left", 11), 714 | (unlocedvtx_checkbox, "left", 11), 715 | (convert_btn, "left", 95), 716 | (informatipn_txt_f, "right", 10), 717 | (add_mesh_btn, "right", 10), 718 | (add_df_btn, "right", 10), 719 | ], 720 | ) 721 | 722 | skinCLusterName = pm.scrollField( 723 | "skn_cl_name", 724 | w=300, 725 | h=30, 726 | p=skin_utils_form, 727 | bgc=[(0.17), (0.18), (0.19)], 728 | editable=True, 729 | wordWrap=False, 730 | ) 731 | selc_mesh_btn = pm.button( 732 | "select_mesh", 733 | l="1. Select Mesh", 734 | p=skin_utils_form, 735 | w=150, 736 | h=30, 737 | bgc=[(0.2), (0.2), (0.2)], 738 | en=1, 739 | ) 740 | rename_skn_btn = pm.button( 741 | "rename_skn", 742 | l="2. Rename SkinC", 743 | p=skin_utils_form, 744 | w=150, 745 | h=30, 746 | bgc=[(0.2), (0.2), (0.2)], 747 | en=1, 748 | ) 749 | 750 | path_textfield = pm.textField( 751 | "df_field", 752 | w=180, 753 | h=41, 754 | pht="Add Deformer", 755 | p=skin_utils_form, 756 | bgc=[(0.17), (0.18), (0.19)], 757 | ) 758 | selectPath_button = pm.iconTextButton( 759 | "df_btn", 760 | style="iconAndTextHorizontal", 761 | image1="addClip.png", 762 | l="Select path", 763 | p=skin_utils_form, 764 | w=120, 765 | h=40, 766 | bgc=[(0.2), (0.2), (0.2)], 767 | en=1, 768 | ) 769 | 770 | import_skn_button = pm.iconTextButton( 771 | "imp_skn", 772 | style="iconAndTextHorizontal", 773 | image1="addClip.png", 774 | l="Import Deformer", 775 | p=skin_utils_form, 776 | w=150, 777 | h=40, 778 | bgc=[(0.2), (0.2), (0.2)], 779 | en=1, 780 | ) 781 | export_skn_button = pm.iconTextButton( 782 | "exp_skn ", 783 | style="iconAndTextHorizontal", 784 | image1="addClip.png", 785 | l="Export Deformer", 786 | p=skin_utils_form, 787 | w=150, 788 | h=40, 789 | bgc=[(0.2), (0.2), (0.2)], 790 | en=1, 791 | ) 792 | 793 | pm.formLayout( 794 | skin_utils_form, 795 | e=1, 796 | attachForm=[ 797 | (skinCLusterName, "top", 10), 798 | (selc_mesh_btn, "top", 45), 799 | (rename_skn_btn, "top", 45), 800 | (import_skn_button, "top", 125), 801 | (export_skn_button, "top", 125), 802 | (path_textfield, "top", 80), 803 | (selectPath_button, "top", 80), 804 | (path_textfield, "left", 10), 805 | (skinCLusterName, "left", 10), 806 | (import_skn_button, "left", 11), 807 | (selc_mesh_btn, "left", 11), 808 | (rename_skn_btn, "right", 11), 809 | (selectPath_button, "right", 10), 810 | (export_skn_button, "right", 10), 811 | ], 812 | ) 813 | 814 | 815 | pm.showWindow(win_name) 816 | 817 | 818 | # radio button change 819 | def crv_skn_cc(): 820 | pm.button(add_mesh_btn, e=1, en=1) 821 | pm.button(add_df_btn, e=1, en=1) 822 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 823 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Skinned Curve") 824 | pm.textField( 825 | informatipn_txt_f, e=1, ed=0, nbg=1, pht="Add a Skinned Curve and Mesh" 826 | ) 827 | 828 | 829 | def softSel_skn_cc(): 830 | pm.button(add_mesh_btn, e=1, en=0) 831 | pm.button(add_df_btn, e=1, en=0) 832 | pm.textField(mesh_textfield, e=1, en=0, pht=" ") 833 | pm.textField(deformer_textfield, e=1, en=0, pht=" ") 834 | pm.textField( 835 | informatipn_txt_f, 836 | e=1, 837 | ed=0, 838 | nbg=1, 839 | pht="Select Verticies/Face with soft selection", 840 | ) 841 | 842 | 843 | def cl_skn_cc(): 844 | pm.button(add_mesh_btn, e=1, en=1) 845 | pm.button(add_df_btn, e=1, en=1) 846 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 847 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Cluster") 848 | pm.textField(informatipn_txt_f, e=1, ed=0, 849 | nbg=1, pht="Add a Cluster and Mesh") 850 | 851 | 852 | def df_skn_cc(): 853 | pm.button(add_mesh_btn, e=1, en=1) 854 | pm.button(add_df_btn, e=1, en=1) 855 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 856 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Deformer") 857 | pm.textField( 858 | informatipn_txt_f, 859 | e=1, 860 | ed=0, 861 | nbg=1, 862 | pht="Add Wire/Wrap/Lattice/DeltaMush and a Mesh", 863 | ) 864 | 865 | 866 | # convert functions 867 | class con_to_skn: 868 | def __init__(self): 869 | self.msh = None 870 | self.defr = None 871 | 872 | def add_mesh(self): 873 | try: 874 | self.msh = str(pm.ls(sl=1)[0]) 875 | if pm.objectType(pm.ls(pm.listHistory(self.msh), typ="mesh")[0]) == "mesh": 876 | pm.textField("mesh_field", e=1, tx=self.msh) 877 | return self.msh 878 | 879 | except: 880 | pm.error("Please select a Mesh") 881 | 882 | def add_deformer(self): 883 | try: 884 | self.defr = str(pm.ls(sl=1)[0]) 885 | option_functions = { 886 | "crv_skn_rb": "curve", 887 | "softsel_skn_rb": "soft", 888 | "restdf_skn_rb": "rest", 889 | "cls_skn_rb": "cluster", 890 | } 891 | option = pm.radioCollection(radio_coll, q=1, sl=1) 892 | 893 | if option in option_functions: 894 | if option_functions[option] == "curve": 895 | if ( 896 | pm.objectType( 897 | pm.ls(pm.listHistory(self.defr), 898 | typ="nurbsCurve")[0] 899 | ) 900 | == "nurbsCurve" 901 | ): 902 | pm.textField("df_field", e=1, tx=self.defr) 903 | return self.defr 904 | 905 | elif option_functions[option] == "cluster": 906 | if ( 907 | pm.objectType( 908 | pm.ls(pm.listHistory(defr), typ="clusterHandle")[0] 909 | ) 910 | == "clusterHandle" 911 | ): 912 | pm.textField("df_field", e=1, tx=self.defr) 913 | return self.defr 914 | 915 | elif option_functions[option] == "soft": 916 | pm.textField("df_field", e=1, tx=self.defr) 917 | return self.defr 918 | 919 | elif option_functions[option] == "rest": 920 | pm.textField("df_field", e=1, tx=self.defr) 921 | return self.defr 922 | 923 | except: 924 | pm.error("Please select the correct deformer") 925 | 926 | def convert_to_skin(self): 927 | dc =deformerConvert(deformer=self.defr, mesh=self.msh) 928 | dc.deformer_skin_convert() 929 | 930 | def rest_deformer(self): 931 | dc =deformerConvert(deformer=self.defr, mesh=self.msh) 932 | dc.rest_deformer_skin_convert() 933 | 934 | def SoftSelection(self): 935 | dc =deformerConvert(deformer=self.defr, mesh=self.msh) 936 | dc.SoftSelectionToConvert() 937 | 938 | def convert_cluster(self): 939 | dc =deformerConvert(deformer=self.defr, mesh=self.msh) 940 | dc.ClusterConvert() 941 | 942 | 943 | con = con_to_skn() 944 | 945 | 946 | def mesh_add(): 947 | c = con.add_mesh() 948 | 949 | 950 | def deformer_add(): 951 | c = con.add_deformer() 952 | 953 | 954 | def convert_to_skin(): 955 | option_functions = { 956 | "crv_skn_rb": con.convert_to_skin, 957 | "softsel_skn_rb": con.SoftSelection, 958 | "restdf_skn_rb": con.rest_deformer, 959 | "cls_skn_rb": con.convert_cluster, 960 | } 961 | option = pm.radioCollection(radio_coll, q=1, sl=1) 962 | start_time = time.time() 963 | 964 | if option in option_functions: 965 | c = option_functions[option]() 966 | else: 967 | print("Conversion Failed") 968 | print(time.time() - start_time, "seconds") -------------------------------------------------------------------------------- /old_files/Vn_v1.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------- 2 | # VN_Magic_Deform_Tool_2.0.py - python Script 3 | # -------------------------------------------------------------- 4 | # 5 | # DESCRIPTION: 6 | # A nicer why to convert any deformer into skincluster 7 | # 8 | # USAGE: 9 | # Copy "VN_Magic_Deform_Tool_2.0.py" in your maya python script editor and run ; 10 | # 11 | # AUTHORS: 12 | # Name : Vishal Nagpal 13 | # Gmail : vishalnagpal878@gamil.com 14 | # linkedin : linkedin.com/in/vishal-nagpal-82975a149 15 | # Copyright ?2022 Vishal Nagpal 16 | # 17 | # VERSIONS: 18 | # 2.0 - Feb 21, 2022 - Initial Release. 19 | # 20 | # Tip for knowledge: 21 | # The vertex distance can be equal to the weight. 22 | 23 | import maya.cmds as cmds 24 | import pymel.core as pm 25 | import time 26 | import math 27 | import sys 28 | 29 | if pm.window("VN_Magic_Deform_Tool", exists=True): 30 | pm.deleteUI("VN_Magic_Deform_Tool", window=True) 31 | 32 | if pm.windowPref( "VN_Magic_Deform_Tool", exists=True ): 33 | pm.windowPref( "VN_Magic_Deform_Tool", remove=True ) 34 | 35 | 36 | window = pm.window("VN Magic Deform Tool",s =0, iconName='Short Name',widthHeight=(300, 433), bgc = [(.1),(.1),(.01)]) 37 | 38 | form = pm.formLayout(numberOfDivisions=100) 39 | Text = pm.text(l ='Just One Click!', h =20, w = 80 ) 40 | 41 | Wire = pm.iconTextButton('WireBase',ann =' Wire to skin convert ' ,style='iconAndTextHorizontal', image1='wire.png',c = 'wireButton()' , label='Wire to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 42 | Lattice = pm.iconTextButton('LatticeBase',ann =' Lattice to skin convert ',style='iconAndTextHorizontal', image1='lattice.png',c = 'latticeButton()',l = 'Lattice to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 43 | shape = pm.iconTextButton('shapeBase',ann =' shape to skin convert ',style='iconAndTextHorizontal', image1='blendShape.png',c = 'blendShapeButton()' ,l = 'BlendShape to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 44 | Wrap = pm.iconTextButton('wrapBase',ann =' Wrap to skin convert ',style='iconAndTextHorizontal', image1='wrap.png',c = 'wrapButton()',l = 'Wrap to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 45 | Cluster = pm.iconTextButton('ClusterBase',ann =' Cluster to skin convert ',style='iconAndTextHorizontal', image1='cluster.png', c = 'clusterButton()',l = 'Cluster to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 46 | SoftS = pm.iconTextButton('SoftSBase',ann =' Soft Selection to skin convert ',style='iconAndTextHorizontal', image1='sculptPinch.png', c = 'SoftButton()',l = 'Soft Selection to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 47 | Curve = pm.iconTextButton('CurveBase',ann =' Curve to skin convert ',style='iconAndTextHorizontal', image1='curveEP.png', c = 'CurveButton()', l = 'Curve to Skin',w=200,h=45, bgc = [(.8),(.8),(.5)]) 48 | 49 | Linkdin = pm.iconTextButton('LinkdinBase',ann =' https://www.linkedin.com/in/vishal-nagpal-82975a149/ ',c ='pm.webBrowser( url="https://www.linkedin.com/in/vishal-nagpal-82975a149/",vis =0)',style='iconAndTextHorizontal',l = 'Linkedin',w=550,h=15, bgc = [(.1),(.1),(.01)]) 50 | Gmail = pm.iconTextButton('GmailBase',ann =' vishalnagpal878@gmail.com ',style='iconAndTextHorizontal',l = 'vishalnagpal878@gmail.com',w=550,h=15, bgc = [(.1),(.1),(.01)]) 51 | 52 | 53 | setingWire = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' select wire first and then Mesh.\n\n ( Wire should have all skinned joints. \n joints should not have any connection. )') 54 | setingLatt = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' select lattice first and then Mesh.\n\n ( lattice should have all skinned joints. \n joints should not have any connection. )') 55 | setingShap = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' select blendshape.\n\n ( Mesh should have only one blenshape on it at a time. )') 56 | setingWrap = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Select SourceMesh then WrapMesh. \n\n ( SourceMesh should have all skinned joints. \n joints should not have any connection. )') 57 | setingClst = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Select cluster first then Mesh.') 58 | setingSoft = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Create Soft Selection.\n\n ( select one cluster at a time.)') 59 | setingCurv = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Select curve first and then Mesh.\n\n ( Curve should have all skinned joints. \n joints should not have any connection. )') 60 | 61 | 62 | pm.formLayout( form, edit=True, 63 | 64 | attachForm= [(Text, 'top', 5), 65 | (Wire, 'top', 40), 66 | (Lattice, 'top', 90), 67 | (shape, 'top', 140), 68 | (Wrap, 'top', 190), 69 | (Cluster, 'top', 240), 70 | (SoftS, 'top', 290), 71 | (Curve, 'top', 342), 72 | (setingWire, 'top', 40), 73 | (setingLatt, 'top', 90), 74 | (setingShap, 'top', 140), 75 | (setingWrap, 'top', 190), 76 | (setingClst, 'top', 240), 77 | (setingSoft, 'top', 295), 78 | (setingCurv, 'top', 348), 79 | (Linkdin, 'top', 393), 80 | (Gmail, 'top', 408), 81 | ], 82 | attachControl=[(Text, 'bottom', 30, Wire), 83 | ], 84 | 85 | attachPosition=[(Text, 'right', 10, 65), 86 | (Wire, 'right', 0, 75), 87 | (Lattice, 'right', 0, 75), 88 | (shape, 'right', 0, 75), 89 | (Wrap, 'right', 0, 75), 90 | (Cluster, 'right', 0, 75), 91 | (SoftS, 'right', 0, 75), 92 | (Curve, 'right', 0, 75), 93 | (setingWire, 'left', 20, 75), 94 | (setingLatt, 'left', 20, 75), 95 | (setingShap, 'left', 20, 75), 96 | (setingWrap, 'left', 20, 75), 97 | (setingClst, 'left', 20, 75), 98 | (setingSoft, 'left', 20, 75), 99 | (setingCurv, 'left', 20, 75), 100 | (Linkdin, 'left', 0, 40), 101 | (Gmail, 'left', 0, 22)], 102 | 103 | ) 104 | 105 | pm.showWindow( window ) 106 | 107 | '''-------------------------------------------------------------------------------------------------------------------- 108 | ----------------------------------------------------------------------------------------------------------------------- 109 | ----------------------------------------------------------------------------------------------------------------------- 110 | --------------------------------------------------------------------------------------------------------------------''' 111 | 112 | '''-----------------------------------------------------------------------------------''' 113 | 114 | #=========================================New_Jnt_And_Rename 115 | def NewJnt(positonN): 116 | objList = cmds.ls("NewVish_*_Jnt") 117 | 118 | alln = [] 119 | 120 | for n in objList: 121 | objNewNum = int(n.split('_')[1]) 122 | alln.append(objNewNum) 123 | alln.sort() 124 | 125 | alln2 = [] 126 | for p in range(1,alln[0]): 127 | alln2.append(p) 128 | 129 | for d in range(len(alln)-1): 130 | for n in range(alln[d]+1,alln[d+1]): 131 | alln2.append(n) 132 | 133 | cmds.select(d = True) 134 | 135 | if alln2 != []: 136 | if alln2[0] < 10: 137 | zro = "0" 138 | cmds.joint(n = "NewVish_"+zro[0]+str(alln2[0])+"_Jnt", p = positonN) 139 | else: 140 | cmds.joint(n = "NewVish_"+str(alln2[0])+"_Jnt", p = positonN) 141 | 142 | if alln2 == []: 143 | if alln[-1]+1 < 10: 144 | zro = "0" 145 | cmds.joint(n = "NewVish_"+zro[0]+str(alln[-1]+1)+"_Jnt", p = positonN) 146 | else: 147 | cmds.joint(n = "NewVish_"+str(alln[-1]+1)+"_Jnt", p = positonN) 148 | 149 | 150 | #=========================================Checking if defaut strings already Exists -- Funtion 151 | 152 | def findString(): 153 | 154 | mysStrings = ['CoolForge','Get_Test_Mesh'] 155 | 156 | for gbgbg in mysStrings: 157 | if cmds.objExists(gbgbg): 158 | print (pm.error( "<<<<<(Please Rename " + gbgbg + " or delete it )>>>>>" )) 159 | 160 | 161 | '''-----------------------------------------------------------------------------------''' 162 | def SimpleCurveConvert(): 163 | 164 | start_time = time.time() 165 | 166 | #=========================================Checking if defaut strings already Exists 167 | 168 | 169 | findString() 170 | 171 | 172 | #=========================================start 173 | 174 | 175 | selection0 = cmds.ls(sl=True) 176 | selecti_00 = selection0[0] 177 | selecti_01 = selection0[1] 178 | cmds.select(d = True) 179 | 180 | #------------------------------------------------------Find_SkinCluster 181 | 182 | def SkinClustor(NamSkinClust): 183 | nodes = [] 184 | 185 | node = cmds.listHistory(NamSkinClust) 186 | for damn in node: 187 | 188 | if cmds.nodeType(damn) == 'skinCluster': 189 | nodes.append(damn) 190 | return nodes 191 | 192 | cluster_00 = SkinClustor(selecti_00) 193 | cluster_01no = SkinClustor(selecti_01) 194 | 195 | #------------------------------------------------------Find_crv_Jnt 196 | 197 | Aljnts = cmds.skinCluster(selecti_00, inf = True, q = True) 198 | 199 | #------------------------------------------------------if_no_skin_on mesh 200 | 201 | if cluster_01no == []: 202 | if pm.objExists("New_Nagpal_Jnt") == False: 203 | pm.joint(n = "New_Nagpal_Jnt") 204 | 205 | cmds.skinCluster('New_Nagpal_Jnt', selecti_01) 206 | 207 | cmds.select(d = True) 208 | cluster_01 = SkinClustor(selecti_01) 209 | #------------------------------------------------------Find_Hold_Jnt 210 | 211 | Meeshjnts = cmds.skinCluster(selecti_01, inf = True, q = True) 212 | 213 | #------------------------------------------------------find unlocked join and lock it 214 | 215 | unlockJnt = [] 216 | 217 | for n in Meeshjnts: 218 | findlock = cmds.getAttr(n+'.liw') 219 | if findlock == False: 220 | unlockJnt.append(n) 221 | 222 | if unlockJnt == []: 223 | cmds.error( "Please unlock one joint" ) 224 | 225 | if len(unlockJnt) > 1: 226 | cmds.error( "Please only one joint should be unlocked" ) 227 | 228 | cmds.setAttr(unlockJnt[0]+'.liw', 1) 229 | 230 | #------------------------------------------------------save_Hold_Jnt_Weight 231 | cmds.select(selecti_01) 232 | polyCount2 = cmds.polyEvaluate( v=True ) 233 | cmds.select(d =True) 234 | 235 | Value = [] 236 | 237 | for fdf in range(polyCount2): 238 | 239 | JntVal = cmds.skinPercent(SkinClustor(selecti_01)[0], selecti_01+'.vtx['+str(fdf)+']' , transform = unlockJnt[0], query=True ) 240 | Value.append(JntVal) 241 | 242 | 243 | #------------------------------------------------------addInflunce_other_Jnts 244 | 245 | for gfs in Aljnts: 246 | 247 | cmds.select(selecti_01) 248 | 249 | cmds.skinCluster(edit=True,ai=gfs,lw = 1) 250 | 251 | 252 | #------------------------------------------------------wire 253 | 254 | pm.wire( selecti_01, w= selecti_00,n = 'CoolForge', gw = False, en= 1.000000, ce= 0.000000, li= 0.000000, dds=[(0, 1000)] ) 255 | pm.setAttr("CoolForge.rotation", 0) 256 | 257 | #------------------------------------------------------ 258 | 259 | for xx in Aljnts: 260 | 261 | whichVer = [] 262 | 263 | verName = cmds.select(xx, r =True) 264 | 265 | cmds.move( 1, xx+'.rotatePivot', y=True, r = True) 266 | 267 | whichVer.append(xx) 268 | 269 | cmds.select(selecti_01) 270 | 271 | cmds.duplicate(n = 'Get_Test_Mesh') 272 | 273 | cmds.move( -1, xx+'.rotatePivot', y=True, r = True) 274 | 275 | cmds.select(selecti_01) 276 | 277 | polyCount = cmds.polyEvaluate( v=True ) 278 | 279 | 280 | set_01ZMain = [] 281 | set_02ZMain = [] 282 | finlDist= [] 283 | 284 | for x in range(3): 285 | 286 | set_01Z = [] 287 | 288 | set_02Z = [] 289 | 290 | #------------------------------------------------------ 291 | for d in range(polyCount): 292 | 293 | Attr = pm.xform(selecti_01+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 294 | 295 | set_01Z.append((Attr)) 296 | 297 | #------------------------------------------------------ 298 | for b in range(polyCount): 299 | 300 | Attrs = pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 301 | 302 | set_02Z.append((Attrs)) 303 | 304 | pm.select(d =True) 305 | 306 | set_01ZMain.append(set_01Z) 307 | set_02ZMain.append(set_02Z) 308 | 309 | #---------------------------------------------------getDiff 310 | for o in range(polyCount): 311 | 312 | x1 = float(set_01ZMain[0][o]) 313 | 314 | y1 = float(set_01ZMain[1][o]) 315 | 316 | z1 = float(set_01ZMain[2][o]) 317 | 318 | x2 = float(set_02ZMain[0][o]) 319 | 320 | y2 = float(set_02ZMain[1][o]) 321 | 322 | z2 = float(set_02ZMain[2][o]) 323 | 324 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 325 | 326 | finlDist.append(findis) 327 | 328 | #---------------------------------------------------percentage_find 329 | FinelWeight = [] 330 | 331 | for nnn in range(len(Value)): 332 | 333 | FinelW = (Value[nnn]/1.0)*finlDist[nnn] 334 | FinelWeight.append(FinelW) 335 | 336 | #---------------------------------------------------addSkin 337 | cmds.setAttr(unlockJnt[0]+'.liw', 0) 338 | for R in range(int(polyCount)): 339 | 340 | 341 | if FinelWeight[R] != 0.0: 342 | 343 | 344 | 345 | cmds.skinPercent( SkinClustor(selecti_01)[0],selecti_01+'.vtx['+str(R)+']', tv=(whichVer[0], FinelWeight[R])) 346 | 347 | 348 | cmds.delete('Get_Test_Mesh') 349 | 350 | for fv in Aljnts: 351 | cmds.setAttr(fv+'.liw', 0) 352 | 353 | cmds.skinCluster(SkinClustor(selecti_01)[0], e = True, ri= unlockJnt[0]) 354 | #---------------------------------------------------delete_Unwanted_Things 355 | if cluster_01no == []: 356 | pm.delete(unlockJnt[0]) 357 | pm.delete('CoolForge') 358 | pm.delete(selecti_00+'BaseWire') 359 | 360 | 361 | 362 | 363 | #---------------------------------------------------Total_Time 364 | 365 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 366 | 367 | #---------------------------------------------------end... 368 | 369 | 370 | 371 | 372 | 373 | 374 | '''-----------------------------------------------------------------------------------''' 375 | 376 | 377 | 378 | 379 | def ClusterConvert(): 380 | 381 | start_time = time.time() 382 | 383 | #=========================================Checking if defaut strings already Exists 384 | 385 | findString() 386 | 387 | #=========================================start 388 | 389 | selection0 = pm.ls(sl=True) 390 | positon = cmds.getAttr(selection0[0]+'.origin')[0] 391 | 392 | pm.select(d =True) 393 | 394 | 395 | #------------------------------------------------------Find_SkinCluster 396 | 397 | 398 | def SkinClustor(NamSkinClust): 399 | nodes = [] 400 | 401 | node = pm.listHistory(NamSkinClust) 402 | for damn in node: 403 | 404 | if pm.nodeType(damn) == 'skinCluster': 405 | nodes.append(damn) 406 | return nodes 407 | 408 | 409 | 410 | #------------------------------------------------------check if both have same skinclister 411 | 412 | 413 | if len(SkinClustor(selection0[-1]))==0: 414 | if pm.objExists("New_Vishu_Jnt") == False: 415 | pm.joint(n = "New_Vishu_Jnt") 416 | 417 | pm.skinCluster('New_Vishu_Jnt', selection0[-1]) 418 | 419 | 420 | #------------------------------------------------------Find_Hold_Jnt 421 | 422 | 423 | Meeshjnts = pm.skinCluster(selection0[-1], inf = True, q = True) 424 | 425 | pm.setAttr(Meeshjnts[0]+'.liw', 1) 426 | 427 | 428 | #------------------------------------------------------ 429 | pm.select(selection0[0], r =True) 430 | for nnn in range(len(selection0)-1): 431 | 432 | pm.select(selection0[nnn],add = True) 433 | 434 | 435 | pm.move( 1, y=True, r = True) 436 | 437 | pm.duplicate(selection0[-1], n = 'Get_Test_Mesh') 438 | 439 | pm.move( -1,y=True, r = True) 440 | 441 | pm.select(selection0[-1]) 442 | 443 | polyCount = pm.polyEvaluate( v=True ) 444 | 445 | 446 | #-----------------------------------------------------set1 447 | 448 | set_01ZMain = [] 449 | set_02ZMain = [] 450 | finlDist= [] 451 | 452 | for x in range(3): 453 | 454 | set_01Z = [] 455 | 456 | set_02Z = [] 457 | 458 | #------------------------------------------------------ 459 | for d in range(polyCount): 460 | 461 | Attr = '%.3f'%pm.xform(selection0[-1]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 462 | 463 | set_01Z.append((Attr)) 464 | 465 | #------------------------------------------------------ 466 | for b in range(polyCount): 467 | 468 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 469 | 470 | set_02Z.append((Attrs)) 471 | 472 | pm.select(d =True) 473 | 474 | set_01ZMain.append(set_01Z) 475 | set_02ZMain.append(set_02Z) 476 | 477 | #---------------------------------------------------getDiff 478 | for o in range(polyCount): 479 | 480 | x1 = float(set_01ZMain[0][o]) 481 | 482 | y1 = float(set_01ZMain[1][o]) 483 | 484 | z1 = float(set_01ZMain[2][o]) 485 | 486 | x2 = float(set_02ZMain[0][o]) 487 | 488 | y2 = float(set_02ZMain[1][o]) 489 | 490 | z2 = float(set_02ZMain[2][o]) 491 | 492 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 493 | 494 | finlDist.append(findis) 495 | 496 | 497 | #---------------------------------------------------addNewJnt and influnence 498 | 499 | if pm.objExists("NewVish_01_Jnt") == False: 500 | pm.joint(n = "NewVish_01_Jnt", p = positon) 501 | else: 502 | NewJnt(positon) 503 | 504 | NwJnt = pm.ls(sl=True) 505 | pm.select(selection0[-1]) 506 | 507 | pm.skinCluster(edit=True,ai= NwJnt[0],lw = 1) 508 | 509 | #---------------------------------------------------addSkin 510 | 511 | for R in range(polyCount): 512 | 513 | pm.setAttr(Meeshjnts[0]+'.liw', 0) 514 | 515 | 516 | 517 | if finlDist[R] != 0.0: 518 | 519 | 520 | 521 | pm.skinPercent( SkinClustor(selection0[-1])[0],selection0[-1]+'.vtx['+str(R)+']', tv=(NwJnt[0], finlDist[R])) 522 | 523 | 524 | pm.delete('Get_Test_Mesh') 525 | 526 | 527 | #---------------------------------------------------Total_Time 528 | 529 | 530 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 531 | 532 | 533 | 534 | 535 | #---------------------------------------------------end.. 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | '''-----------------------------------------------------------------------------------''' 544 | 545 | 546 | def SoftConvert(): 547 | 548 | start_time = time.time() 549 | 550 | #=========================================Checking if defaut strings already Exists 551 | 552 | findString() 553 | 554 | #=========================================start 555 | 556 | selection0 = cmds.ls(sl=True) 557 | selecti_00 = selection0[0] 558 | cmds.cluster(n = 'VishClust') 559 | 560 | shapename = cmds.listHistory(selecti_00)[0] 561 | positon = cmds.getAttr("VishClustHandleShape.origin")[0] 562 | cmds.delete('VishClust') 563 | 564 | cmds.select(shapename) 565 | cmds.pickWalk(d = 'up') 566 | 567 | transName = cmds.ls(sl=True) 568 | 569 | cmds.select(d =True) 570 | 571 | 572 | #------------------------------------------------------Find_SkinCluster 573 | 574 | 575 | def SkinClustor(NamSkinClust): 576 | nodes = [] 577 | 578 | node = cmds.listHistory(NamSkinClust) 579 | for damn in node: 580 | 581 | if cmds.nodeType(damn) == 'skinCluster': 582 | nodes.append(damn) 583 | return nodes 584 | 585 | cluster_01no = SkinClustor(transName) 586 | #------------------------------------------------------if_no_skin_on_mesh_thenadd_one_joint 587 | 588 | if cluster_01no == []: 589 | 590 | if cmds.objExists("New_VishHold_Jnt") == False: 591 | cmds.joint(n = "New_VishHold_Jnt") 592 | 593 | cmds.skinCluster('New_VishHold_Jnt', transName) 594 | 595 | 596 | cmds.select(d = True) 597 | cluster_01 = SkinClustor(transName) 598 | 599 | 600 | newJnt01 = [] 601 | 602 | if cmds.objExists("NewVish_01_Jnt") == True: 603 | cmds.select(d = True) 604 | NewJnt(positon) 605 | NwJnt = cmds.ls(sl=True) 606 | newJnt01.append(NwJnt[0]) 607 | cmds.select(transName) 608 | cmds.skinCluster(edit=True,ai=NwJnt[0],lw = 1, wt = 0) 609 | cmds.select(d = True) 610 | 611 | if cmds.objExists("NewVish_01_Jnt") == False: 612 | cmds.select(d = True) 613 | cmds.joint(n = "NewVish_01_Jnt", p = positon ) 614 | NwJnt = cmds.ls(sl=True) 615 | newJnt01.append(NwJnt[0]) 616 | cmds.select(transName) 617 | cmds.skinCluster(edit=True,ai="NewVish_01_Jnt",lw = 1, wt = 0) 618 | #------------------------------------------------------Find_Hold_Jnt 619 | 620 | 621 | Meeshjnts = cmds.skinCluster(transName, inf = True, q = True) 622 | 623 | cmds.setAttr(Meeshjnts[0]+'.liw', 1) 624 | 625 | 626 | #------------------------------------------------------ 627 | 628 | cmds.select(selecti_00, r =True) 629 | for nnn in range(len(selection0)): 630 | cmds.select(selection0[nnn],add = True) 631 | 632 | cmds.move( 1, y=True, r = True) 633 | 634 | cmds.duplicate(transName[0], n = 'Get_Test_Mesh') 635 | 636 | cmds.move( -1,y=True, r = True) 637 | 638 | cmds.select(transName[0]) 639 | 640 | polyCount = cmds.polyEvaluate( v=True ) 641 | 642 | 643 | #-----------------------------------------------------set1 644 | 645 | set_01ZMain = [] 646 | set_02ZMain = [] 647 | finlDist= [] 648 | 649 | for x in range(3): 650 | 651 | set_01Z = [] 652 | 653 | set_02Z = [] 654 | 655 | #------------------------------------------------------ 656 | for d in range(polyCount): 657 | 658 | Attr = '%.3f'%pm.xform(transName[0]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 659 | 660 | set_01Z.append((Attr)) 661 | 662 | #------------------------------------------------------ 663 | for b in range(polyCount): 664 | 665 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 666 | 667 | set_02Z.append((Attrs)) 668 | 669 | pm.select(d =True) 670 | 671 | set_01ZMain.append(set_01Z) 672 | set_02ZMain.append(set_02Z) 673 | 674 | #---------------------------------------------------getDiff 675 | for o in range(polyCount): 676 | 677 | x1 = float(set_01ZMain[0][o]) 678 | 679 | y1 = float(set_01ZMain[1][o]) 680 | 681 | z1 = float(set_01ZMain[2][o]) 682 | 683 | x2 = float(set_02ZMain[0][o]) 684 | 685 | y2 = float(set_02ZMain[1][o]) 686 | 687 | z2 = float(set_02ZMain[2][o]) 688 | 689 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 690 | 691 | finlDist.append(findis) 692 | 693 | 694 | #---------------------------------------------------addSkin 695 | 696 | for R in range(polyCount): 697 | 698 | cmds.setAttr(Meeshjnts[0]+'.liw', 0) 699 | 700 | 701 | 702 | if finlDist[R] != 0.0: 703 | 704 | 705 | 706 | cmds.skinPercent( SkinClustor(transName[0])[0],transName[0]+'.vtx['+str(R)+']', tv=(newJnt01[0], finlDist[R])) 707 | 708 | 709 | cmds.delete('Get_Test_Mesh') 710 | 711 | 712 | #---------------------------------------------------Total_Time 713 | 714 | 715 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 716 | 717 | 718 | 719 | 720 | #---------------------------------------------------end.. 721 | 722 | 723 | '''-----------------------------------------------------------------------------------''' 724 | 725 | 726 | def WrapCurveWireLatticeConvet(): 727 | 728 | start_time = time.time() 729 | 730 | #=========================================Checking if defaut strings already Exists 731 | 732 | findString() 733 | 734 | #=========================================start 735 | 736 | selection0 = cmds.ls(sl=True) 737 | 738 | cmds.select(d = True) 739 | 740 | #=========================================if_Wire_rotation_Zero 741 | def checkWire(NamwireDfm): 742 | nodes = [] 743 | 744 | node = cmds.listHistory(NamwireDfm) 745 | for damn in node: 746 | 747 | if cmds.nodeType(damn) == 'wire': 748 | nodes.append(damn) 749 | return nodes 750 | 751 | rotVal = [] 752 | if checkWire(selection0[1]) != []: 753 | rotVal2 = pm.getAttr(checkWire(selection0[1])[0]+".rotation") 754 | rotVal.append(rotVal2) 755 | if rotVal != 0.0: 756 | pm.setAttr(checkWire(selection0[1])[0]+".rotation", 0.0) 757 | 758 | #------------------------------------------------------Find_SkinCluster 759 | 760 | 761 | def SkinClustor(NamSkinClust): 762 | nodes = [] 763 | 764 | node = cmds.listHistory(NamSkinClust) 765 | for damn in node: 766 | 767 | if cmds.nodeType(damn) == 'skinCluster': 768 | nodes.append(damn) 769 | return nodes 770 | 771 | #------------------------------------------------------check if both have same skinclister 772 | meshClust = SkinClustor(selection0[1]) 773 | wireClust = SkinClustor(selection0[0]) 774 | 775 | if len(SkinClustor(selection0[0]))==0: 776 | print (pm.error( "<<<<<(no skin on wire)>>>>>" )) 777 | 778 | if len(SkinClustor(selection0[0]))==1: 779 | if wireClust[0] in meshClust: 780 | meshClust.remove(wireClust[0]) 781 | 782 | if SkinClustor(selection0[0]) != 0: 783 | for n in SkinClustor(selection0[0]): 784 | if n in meshClust: 785 | meshClust.remove(n) 786 | 787 | if meshClust==[]: 788 | if cmds.objExists("New_Vishu_Jnt") == False: 789 | cmds.joint(n = "New_Vishu_Jnt") 790 | 791 | cmds.skinCluster('New_Vishu_Jnt', selection0[1]) 792 | 793 | #------------------------------------------------------Find_Hold_Jnt 794 | 795 | 796 | Meeshjnts = cmds.skinCluster(selection0[1], inf = True, q = True) 797 | 798 | cmds.setAttr(Meeshjnts[0]+'.liw', 1) 799 | 800 | 801 | #------------------------------------------------------Find_deformer_Jnt 802 | 803 | 804 | Aljnts = cmds.skinCluster(selection0[0], inf = True, q = True) 805 | 806 | 807 | #------------------------------------------------------addInflunce_other_Jnts 808 | 809 | 810 | 811 | for gfs in Aljnts: 812 | 813 | if gfs not in Meeshjnts: 814 | 815 | cmds.select(selection0[1]) 816 | 817 | cmds.skinCluster(edit=True,ai=gfs,lw = 1) 818 | 819 | 820 | 821 | #------------------------------------------------------ 822 | 823 | 824 | for xx in Aljnts: 825 | 826 | whichVer = [] 827 | 828 | verName = cmds.select(xx, r =True) 829 | 830 | cmds.move( 1, xx+'.rotatePivot', y=True, r = True) 831 | 832 | whichVer.append(xx) 833 | 834 | cmds.select(selection0[1]) 835 | 836 | cmds.duplicate(n = 'Get_Test_Mesh') 837 | 838 | cmds.move( -1, xx+'.rotatePivot', y=True, r = True) 839 | 840 | cmds.select(selection0[1]) 841 | 842 | polyCount = cmds.polyEvaluate( v=True ) 843 | 844 | 845 | set_01ZMain = [] 846 | set_02ZMain = [] 847 | finlDist= [] 848 | 849 | for x in range(3): 850 | 851 | set_01Z = [] 852 | 853 | set_02Z = [] 854 | 855 | #------------------------------------------------------ 856 | for d in range(polyCount): 857 | 858 | Attr = '%.3f'%pm.xform(selection0[1]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 859 | 860 | set_01Z.append((Attr)) 861 | 862 | #------------------------------------------------------ 863 | for b in range(polyCount): 864 | 865 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 866 | 867 | set_02Z.append((Attrs)) 868 | 869 | pm.select(d =True) 870 | 871 | set_01ZMain.append(set_01Z) 872 | set_02ZMain.append(set_02Z) 873 | 874 | #---------------------------------------------------getDiff 875 | for o in range(polyCount): 876 | 877 | x1 = float(set_01ZMain[0][o]) 878 | 879 | y1 = float(set_01ZMain[1][o]) 880 | 881 | z1 = float(set_01ZMain[2][o]) 882 | 883 | x2 = float(set_02ZMain[0][o]) 884 | 885 | y2 = float(set_02ZMain[1][o]) 886 | 887 | z2 = float(set_02ZMain[2][o]) 888 | 889 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 890 | 891 | finlDist.append(findis) 892 | 893 | 894 | #---------------------------------------------------addSkin 895 | 896 | for R in range(int(polyCount)): 897 | 898 | cmds.setAttr(Meeshjnts[0]+'.liw', 0) 899 | 900 | 901 | 902 | if finlDist[R] != 0.0: 903 | 904 | 905 | 906 | cmds.skinPercent( SkinClustor(selection0[1])[0],selection0[1]+'.vtx['+str(R)+']', tv=(whichVer[0], finlDist[R])) 907 | 908 | 909 | cmds.delete('Get_Test_Mesh') 910 | 911 | 912 | if checkWire(selection0[1]) != []: 913 | pm.setAttr(checkWire(selection0[1])[0]+".rotation", rotVal[0]) 914 | #---------------------------------------------------Total_Time 915 | 916 | 917 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 918 | 919 | #---------------------------------------------------end.. 920 | 921 | 922 | 923 | 924 | 925 | '''---------------------------------------------------------------------------------''' 926 | def BlendShapeConvert(): 927 | 928 | start_time = time.time() 929 | 930 | #=========================================Checking if defaut strings already Exists 931 | 932 | findString() 933 | 934 | #=========================================start 935 | 936 | transName = pm.ls(sl=True) 937 | 938 | pm.listHistory(transName[0]) 939 | 940 | pm.select(d =True) 941 | 942 | #------------------------------------------------------Find_SkinCluster 943 | 944 | def BlendShape(NamBlensSHape): 945 | nodes = [] 946 | 947 | node = pm.listHistory(NamBlensSHape) 948 | for damn in node: 949 | 950 | if pm.nodeType(damn) == 'blendShape': 951 | nodes.append(damn) 952 | return nodes 953 | 954 | WeightName = pm.listAttr(BlendShape(transName[0])[0]+'.w', m =True) 955 | 956 | #------------------------------------------------------Find_SkinCluster 957 | 958 | 959 | def SkinClustor(NamSkinClust): 960 | nodes = [] 961 | 962 | node = pm.listHistory(NamSkinClust) 963 | for damn in node: 964 | 965 | if pm.nodeType(damn) == 'skinCluster': 966 | nodes.append(damn) 967 | return nodes 968 | 969 | #------------------------------------------------------check if both have same skinclister 970 | 971 | if len(SkinClustor(transName[0]))==0: 972 | if pm.objExists("New_Vishu_Jnt") == False: 973 | pm.joint(n = "New_Vishu_Jnt") 974 | 975 | pm.skinCluster('New_Vishu_Jnt', transName[0]) 976 | 977 | #------------------------------------------------------Find_Hold_Jnt 978 | 979 | MeshJnt = pm.skinCluster(transName[0], inf = True, q = True) 980 | 981 | pm.setAttr(MeshJnt[0]+'.liw', 1) 982 | 983 | #------------------------------------------------------ 984 | 985 | pm.setAttr(BlendShape(transName[0])[0]+'.'+WeightName[0], 1) 986 | 987 | pm.duplicate(transName[0], n = 'Get_Test_Mesh') 988 | 989 | pm.setAttr(BlendShape(transName[0])[0]+'.'+WeightName[0], 0) 990 | 991 | pm.select(transName[0]) 992 | 993 | polyCount = pm.polyEvaluate( v=True ) 994 | 995 | pm.select(d =True) 996 | 997 | #---------------------------------------------------addNewJnt and influnence 998 | 999 | if pm.objExists("NewVish_01_Jnt") == False: 1000 | pm.joint(n = "NewVish_01_Jnt") 1001 | else: 1002 | NewJnt((0.0,0.0,0.0)) 1003 | 1004 | NwJnt = pm.ls(sl=True) 1005 | pm.select(transName[0]) 1006 | 1007 | pm.skinCluster(edit=True,ai= NwJnt[0],lw = 1) 1008 | 1009 | #-----------------------------------------------------set1 1010 | 1011 | set_01ZMain = [] 1012 | set_02ZMain = [] 1013 | finlDist= [] 1014 | 1015 | 1016 | finlDistGetBig = [] 1017 | 1018 | 1019 | for x in range(3): 1020 | 1021 | set_01Z = [] 1022 | 1023 | set_02Z = [] 1024 | 1025 | #------------------------------------------------------ 1026 | for d in range(polyCount): 1027 | 1028 | Attr = '%.3f'%pm.xform(transName[0]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 1029 | 1030 | set_01Z.append((Attr)) 1031 | 1032 | #------------------------------------------------------ 1033 | for b in range(polyCount): 1034 | 1035 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 1036 | 1037 | set_02Z.append((Attrs)) 1038 | 1039 | pm.select(d =True) 1040 | 1041 | set_01ZMain.append(set_01Z) 1042 | set_02ZMain.append(set_02Z) 1043 | 1044 | #---------------------------------------------------getDiff 1045 | for o in range(polyCount): 1046 | 1047 | x1 = float(set_01ZMain[0][o]) 1048 | 1049 | y1 = float(set_01ZMain[1][o]) 1050 | 1051 | z1 = float(set_01ZMain[2][o]) 1052 | 1053 | x2 = float(set_02ZMain[0][o]) 1054 | 1055 | y2 = float(set_02ZMain[1][o]) 1056 | 1057 | z2 = float(set_02ZMain[2][o]) 1058 | 1059 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 1060 | 1061 | finlDist.append(findis) 1062 | finlDistGetBig.append(findis) 1063 | 1064 | #---------------------------------------------------addSkin 1065 | finlDistGetBig.sort() 1066 | finlDistGetBigNum = finlDistGetBig[-1] 1067 | 1068 | for R in range(polyCount): 1069 | 1070 | pm.setAttr(MeshJnt[0]+'.liw', 0) 1071 | 1072 | 1073 | if finlDist[R] != 0.0 : 1074 | 1075 | pm.skinPercent( SkinClustor(transName[0])[0],transName[0]+'.vtx['+str(R)+']', tv=(NwJnt[0], finlDist[R]/finlDistGetBigNum)) 1076 | 1077 | pm.delete('Get_Test_Mesh') 1078 | 1079 | #---------------------------------------------------Total_Time 1080 | 1081 | 1082 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 1083 | 1084 | 1085 | 1086 | #---------------------------------------------------end.. 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | '''------------------------------------------------------------''' 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | #=========================================Lattice 1102 | def latticeButton(): 1103 | selectedo = cmds.ls(sl=True) 1104 | listo = cmds.listHistory(selectedo[1]) 1105 | allObjecto = [] 1106 | for s in listo: 1107 | if cmds.nodeType(s) == 'lattice': 1108 | allObjecto.append(s) 1109 | 1110 | if len(allObjecto) !=0: 1111 | WrapCurveWireLatticeConvet() 1112 | print('Lattice',allObjecto) 1113 | else: 1114 | cmds.error( "No_Lattice" ) 1115 | #========================================= 1116 | 1117 | #=========================================wire---- 1118 | def wireButton(): 1119 | selectedo = cmds.ls(sl=True) 1120 | listo = cmds.listHistory(selectedo[1]) 1121 | allObjecto = [] 1122 | for s in listo: 1123 | if cmds.nodeType(s) == 'wire': 1124 | allObjecto.append(s) 1125 | 1126 | if len(allObjecto) !=0: 1127 | WrapCurveWireLatticeConvet() 1128 | print('Wire',allObjecto) 1129 | else: 1130 | cmds.error( "No_Wire" ) 1131 | #========================================= 1132 | 1133 | #=========================================wrap---- 1134 | def wrapButton(): 1135 | selectedo = cmds.ls(sl=True) 1136 | listo = cmds.listHistory(selectedo[1]) 1137 | allObjecto = [] 1138 | for s in listo: 1139 | if cmds.nodeType(s) == 'wrap': 1140 | allObjecto.append(s) 1141 | 1142 | if len(allObjecto) !=0: 1143 | WrapCurveWireLatticeConvet() 1144 | print('Wrap',allObjecto) 1145 | else: 1146 | cmds.error( "No_Wrap" ) 1147 | #========================================= 1148 | 1149 | #=========================================blendShape---- 1150 | def blendShapeButton(): 1151 | selectedo = cmds.ls(sl=True) 1152 | listo = cmds.listHistory(selectedo[0]) 1153 | allObjecto = [] 1154 | for s in listo: 1155 | if cmds.nodeType(s) == 'blendShape': 1156 | allObjecto.append(s) 1157 | 1158 | if len(allObjecto) !=0: 1159 | BlendShapeConvert() 1160 | print('BlendShape',allObjecto) 1161 | else: 1162 | cmds.error( "No_BlendShape" ) 1163 | #========================================= 1164 | 1165 | #=========================================clusterHandle---- 1166 | def clusterButton(): 1167 | selectedo = cmds.ls(sl=True) 1168 | listo = cmds.listHistory(selectedo[-1]) 1169 | allObjecto = [] 1170 | for s in listo: 1171 | if cmds.nodeType(s) == 'cluster': 1172 | allObjecto.append(s) 1173 | 1174 | if len(allObjecto) !=0: 1175 | ClusterConvert() 1176 | print('Cluster',allObjecto) 1177 | else: 1178 | cmds.error( "No_Cluster" ) 1179 | #========================================= 1180 | 1181 | #=========================================SoftSelection 1182 | def SoftButton(): 1183 | checkSoft = cmds.softSelect(q = True, sse=True) 1184 | 1185 | selectedo = cmds.ls(sl=True) 1186 | 1187 | if cmds.nodeType(selectedo[0]) == 'mesh' and checkSoft == 1: 1188 | SoftConvert() 1189 | print('SoftSelection',selectedo) 1190 | else: 1191 | cmds.error( "No_SoftSelection" ) 1192 | 1193 | #========================================= 1194 | 1195 | #=========================================Curve 1196 | def CurveButton(): 1197 | pm.pickWalk(d = 'down') 1198 | selectedo = cmds.ls(sl=True) 1199 | pm.pickWalk(d = 'up') 1200 | if cmds.nodeType(selectedo[0]) == 'nurbsCurve' and cmds.nodeType(selectedo[1]) == 'mesh' : 1201 | SimpleCurveConvert() 1202 | print('Curve') 1203 | else: 1204 | cmds.error( "No_Curve" ) 1205 | #========================================= 1206 | 1207 | '''------------------------------------------------------------end''' -------------------------------------------------------------------------------- /old_files/VnMagicTool_v2.py: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------- 2 | # VN_Magic_Deform_Tool_2.0.py - python Script 3 | # -------------------------------------------------------------- 4 | # 5 | # DESCRIPTION: 6 | # A nicer why to convert any deformer into skincluster 7 | # 8 | # USAGE: 9 | # Copy "VN_Magic_Deform_Tool_2.0.py" in your maya python script editor and run ; 10 | # 11 | # AUTHORS: 12 | # Name : Vishal Nagpal 13 | # Gmail : vishalnagpal878@gamil.com 14 | # linkedin : linkedin.com/in/vishal-nagpal-82975a149 15 | # Copyright ©2022 Vishal Nagpal 16 | # 17 | # VERSIONS: 18 | # 2.0 - Feb 21, 2022 - Initial Release. 19 | # 20 | # Tip for knowledge: 21 | # The vertex distance can be equal to the weight. 22 | 23 | 24 | import pymel.core as pm 25 | import time 26 | import math 27 | import sys 28 | 29 | if pm.window("VN_Magic_Deform_Tool", exists=True): 30 | pm.deleteUI("VN_Magic_Deform_Tool", window=True) 31 | 32 | if pm.windowPref( "VN_Magic_Deform_Tool", exists=True ): 33 | pm.windowPref( "VN_Magic_Deform_Tool", remove=True ) 34 | 35 | 36 | window = pm.window("VN Magic Deform Tool",s =0, iconName='Short Name',widthHeight=(300, 433), bgc = [(.1),(.1),(.01)]) 37 | 38 | form = pm.formLayout(numberOfDivisions=100) 39 | Text = pm.text(l ='Just One Click!', h =20, w = 80 ) 40 | 41 | Wire = pm.iconTextButton('WireBase',ann =' Wire to skin convert ' ,style='iconAndTextHorizontal', image1='wire.png',c = 'wireButton()' , label='Wire to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 42 | Lattice = pm.iconTextButton('LatticeBase',ann =' Lattice to skin convert ',style='iconAndTextHorizontal', image1='lattice.png',c = 'latticeButton()',l = 'Lattice to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 43 | shape = pm.iconTextButton('shapeBase',ann =' shape to skin convert ',style='iconAndTextHorizontal', image1='blendShape.png',c = 'blendShapeButton()' ,l = 'BlendShape to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 44 | Wrap = pm.iconTextButton('wrapBase',ann =' Wrap to skin convert ',style='iconAndTextHorizontal', image1='wrap.png',c = 'wrapButton()',l = 'Wrap to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 45 | Cluster = pm.iconTextButton('ClusterBase',ann =' Cluster to skin convert ',style='iconAndTextHorizontal', image1='cluster.png', c = 'clusterButton()',l = 'Cluster to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 46 | SoftS = pm.iconTextButton('SoftSBase',ann =' Soft Selection to skin convert ',style='iconAndTextHorizontal', image1='sculptPinch.png', c = 'SoftButton()',l = 'Soft Selection to Skin',w=200,h=35, bgc = [(.21),(.42),(.3)]) 47 | Curve = pm.iconTextButton('CurveBase',ann =' Curve to skin convert ',style='iconAndTextHorizontal', image1='curveEP.png', c = 'CurveButton()', l = 'Curve to Skin',w=200,h=45, bgc = [(.8),(.8),(.5)]) 48 | 49 | Linkdin = pm.iconTextButton('LinkdinBase',ann =' https://www.linkedin.com/in/vishal-nagpal-82975a149/ ',c ='pm.webBrowser( url="https://www.linkedin.com/in/vishal-nagpal-82975a149/",vis =0)',style='iconAndTextHorizontal',l = 'Linkedin',w=550,h=15, bgc = [(.1),(.1),(.01)]) 50 | Gmail = pm.iconTextButton('GmailBase',ann =' vishalnagpal878@gmail.com ',style='iconAndTextHorizontal',l = 'vishalnagpal878@gmail.com',w=550,h=15, bgc = [(.1),(.1),(.01)]) 51 | 52 | 53 | setingWire = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' select wire first and then Mesh.\n\n ( Wire should have all skinned joints. \n joints should not have any connection. )') 54 | setingLatt = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' select lattice first and then Mesh.\n\n ( lattice should have all skinned joints. \n joints should not have any connection. )') 55 | setingShap = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' select blendshape.\n\n ( Mesh should have only one blenshape on it at a time. )') 56 | setingWrap = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Select SourceMesh then WrapMesh. \n\n ( SourceMesh should have all skinned joints. \n joints should not have any connection. )') 57 | setingClst = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Select cluster first then Mesh.') 58 | setingSoft = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Create Soft Selection.\n\n ( select one cluster at a time.)') 59 | setingCurv = pm.symbolButton(i = 'menuIconHelp.png', h= 30,w = 30,ann =' Select curve first and then Mesh.\n\n ( Curve should have all skinned joints. \n joints should not have any connection. )') 60 | 61 | 62 | pm.formLayout( form, edit=True, 63 | 64 | attachForm= [(Text, 'top', 5), 65 | (Wire, 'top', 40), 66 | (Lattice, 'top', 90), 67 | (shape, 'top', 140), 68 | (Wrap, 'top', 190), 69 | (Cluster, 'top', 240), 70 | (SoftS, 'top', 290), 71 | (Curve, 'top', 342), 72 | (setingWire, 'top', 40), 73 | (setingLatt, 'top', 90), 74 | (setingShap, 'top', 140), 75 | (setingWrap, 'top', 190), 76 | (setingClst, 'top', 240), 77 | (setingSoft, 'top', 295), 78 | (setingCurv, 'top', 348), 79 | (Linkdin, 'top', 393), 80 | (Gmail, 'top', 408), 81 | ], 82 | attachControl=[(Text, 'bottom', 30, Wire), 83 | ], 84 | 85 | attachPosition=[(Text, 'right', 10, 65), 86 | (Wire, 'right', 0, 75), 87 | (Lattice, 'right', 0, 75), 88 | (shape, 'right', 0, 75), 89 | (Wrap, 'right', 0, 75), 90 | (Cluster, 'right', 0, 75), 91 | (SoftS, 'right', 0, 75), 92 | (Curve, 'right', 0, 75), 93 | (setingWire, 'left', 20, 75), 94 | (setingLatt, 'left', 20, 75), 95 | (setingShap, 'left', 20, 75), 96 | (setingWrap, 'left', 20, 75), 97 | (setingClst, 'left', 20, 75), 98 | (setingSoft, 'left', 20, 75), 99 | (setingCurv, 'left', 20, 75), 100 | (Linkdin, 'left', 0, 40), 101 | (Gmail, 'left', 0, 22)], 102 | 103 | ) 104 | 105 | pm.showWindow( window ) 106 | 107 | '''-------------------------------------------------------------------------------------------------------------------- 108 | ----------------------------------------------------------------------------------------------------------------------- 109 | ----------------------------------------------------------------------------------------------------------------------- 110 | --------------------------------------------------------------------------------------------------------------------''' 111 | 112 | '''-----------------------------------------------------------------------------------''' 113 | 114 | #=========================================New_Jnt_And_Rename 115 | def NewJnt(positonN): 116 | objList = cmds.ls("NewVish_*_Jnt") 117 | 118 | alln = [] 119 | 120 | for n in objList: 121 | objNewNum = int(n.split('_')[1]) 122 | alln.append(objNewNum) 123 | alln.sort() 124 | 125 | alln2 = [] 126 | for p in range(1,alln[0]): 127 | alln2.append(p) 128 | 129 | for d in range(len(alln)-1): 130 | for n in range(alln[d]+1,alln[d+1]): 131 | alln2.append(n) 132 | 133 | cmds.select(d = True) 134 | 135 | if alln2 != []: 136 | if alln2[0] < 10: 137 | zro = "0" 138 | cmds.joint(n = "NewVish_"+zro[0]+str(alln2[0])+"_Jnt", p = positonN) 139 | else: 140 | cmds.joint(n = "NewVish_"+str(alln2[0])+"_Jnt", p = positonN) 141 | 142 | if alln2 == []: 143 | if alln[-1]+1 < 10: 144 | zro = "0" 145 | cmds.joint(n = "NewVish_"+zro[0]+str(alln[-1]+1)+"_Jnt", p = positonN) 146 | else: 147 | cmds.joint(n = "NewVish_"+str(alln[-1]+1)+"_Jnt", p = positonN) 148 | 149 | 150 | #=========================================Checking if defaut strings already Exists -- Funtion 151 | 152 | def findString(): 153 | 154 | mysStrings = ['CoolForge','Get_Test_Mesh'] 155 | 156 | for gbgbg in mysStrings: 157 | if cmds.objExists(gbgbg): 158 | print (pm.error( "<<<<<(Please Rename " + gbgbg + " or delete it )>>>>>" )) 159 | 160 | 161 | '''-----------------------------------------------------------------------------------''' 162 | def SimpleCurveConvert(): 163 | 164 | start_time = time.time() 165 | 166 | #=========================================Checking if defaut strings already Exists 167 | 168 | 169 | findString() 170 | 171 | 172 | #=========================================start 173 | 174 | 175 | selection0 = cmds.ls(sl=True) 176 | selecti_00 = selection0[0] 177 | selecti_01 = selection0[1] 178 | cmds.select(d = True) 179 | 180 | #------------------------------------------------------Find_SkinCluster 181 | 182 | def SkinClustor(NamSkinClust): 183 | nodes = [] 184 | 185 | node = cmds.listHistory(NamSkinClust) 186 | for damn in node: 187 | 188 | if cmds.nodeType(damn) == 'skinCluster': 189 | nodes.append(damn) 190 | return nodes 191 | 192 | cluster_00 = SkinClustor(selecti_00) 193 | cluster_01no = SkinClustor(selecti_01) 194 | 195 | #------------------------------------------------------Find_crv_Jnt 196 | 197 | Aljnts = cmds.skinCluster(selecti_00, inf = True, q = True) 198 | 199 | #------------------------------------------------------if_no_skin_on mesh 200 | 201 | if cluster_01no == []: 202 | if pm.objExists("New_Nagpal_Jnt") == False: 203 | pm.joint(n = "New_Nagpal_Jnt") 204 | 205 | cmds.skinCluster('New_Nagpal_Jnt', selecti_01) 206 | 207 | cmds.select(d = True) 208 | cluster_01 = SkinClustor(selecti_01) 209 | #------------------------------------------------------Find_Hold_Jnt 210 | 211 | Meeshjnts = cmds.skinCluster(selecti_01, inf = True, q = True) 212 | 213 | #------------------------------------------------------find unlocked join and lock it 214 | 215 | unlockJnt = [] 216 | 217 | for n in Meeshjnts: 218 | findlock = cmds.getAttr(n+'.liw') 219 | if findlock == False: 220 | unlockJnt.append(n) 221 | 222 | if unlockJnt == []: 223 | cmds.error( "Please unlock one joint" ) 224 | 225 | if len(unlockJnt) > 1: 226 | cmds.error( "Please only one joint should be unlocked" ) 227 | 228 | cmds.setAttr(unlockJnt[0]+'.liw', 1) 229 | 230 | #------------------------------------------------------solvVert 231 | 232 | def solvVert(vertcnt): 233 | 234 | totalCounts = [] 235 | 236 | for vert in vertcnt: 237 | 238 | split01 = vert.split("[") 239 | split02 = split01[-1].split("]") 240 | 241 | start = int(split02[0]) 242 | 243 | totalCounts.append(str(start)) 244 | 245 | return (totalCounts) 246 | 247 | 248 | #------------------------------------------------------getEffectedVrt 249 | 250 | cmds.select(d = True) 251 | 252 | gotselected = [] 253 | if len(cluster_01no) == 1: 254 | cmds.skinCluster(cluster_01no, e=True, selectInfluenceVerts = unlockJnt) 255 | effectdVrt0 = cmds.ls(sl=True, fl =1 ) 256 | gotselected = solvVert(effectdVrt0) 257 | 258 | if len(cluster_01no) != 1: 259 | polyCo = cmds.polyEvaluate(selecti_01, v=True ) 260 | for i in range(polyCo): 261 | gotselected.append(str(i)) 262 | 263 | 264 | cmds.select(d = True) 265 | 266 | 267 | #------------------------------------------------------save_Hold_Jnt_Weight 268 | cmds.select(selecti_01) 269 | #polyCount2 = cmds.polyEvaluate( v=True ) 270 | cmds.select(d =True) 271 | 272 | Value = [] 273 | 274 | for fdf in gotselected: 275 | 276 | JntVal = cmds.skinPercent(SkinClustor(selecti_01)[0], selecti_01+'.vtx['+fdf+']' , transform = unlockJnt[0], query=True ) 277 | Value.append(JntVal) 278 | 279 | 280 | #------------------------------------------------------addInflunce_other_Jnts 281 | 282 | for gfs in Aljnts: 283 | 284 | cmds.select(selecti_01) 285 | 286 | cmds.skinCluster(edit=True,ai=gfs,lw = 1) 287 | 288 | 289 | #------------------------------------------------------wire 290 | 291 | pm.wire( selecti_01, w= selecti_00,n = 'CoolForge', gw = False, en= 1.000000, ce= 0.000000, li= 0.000000, dds=[(0, 1000)] ) 292 | pm.setAttr("CoolForge.rotation", 0) 293 | 294 | #------------------------------------------------------ 295 | 296 | for xx in Aljnts: 297 | 298 | whichVer = [] 299 | 300 | verName = cmds.select(xx, r =True) 301 | 302 | cmds.move( 1, xx+'.rotatePivot', y=True, r = True) 303 | 304 | whichVer.append(xx) 305 | 306 | cmds.select(selecti_01) 307 | 308 | cmds.duplicate(n = 'Get_Test_Mesh') 309 | 310 | cmds.move( -1, xx+'.rotatePivot', y=True, r = True) 311 | 312 | cmds.select(selecti_01) 313 | 314 | #polyCount = cmds.polyEvaluate( v=True ) 315 | 316 | 317 | set_01ZMain = [] 318 | set_02ZMain = [] 319 | finlDist= [] 320 | 321 | for x in range(3): 322 | 323 | set_01Z = [] 324 | 325 | set_02Z = [] 326 | 327 | #------------------------------------------------------ 328 | for d in gotselected: 329 | 330 | Attr = pm.xform(selecti_01+'.vtx['+d+']', q =True, ws = True, t=True)[x] 331 | 332 | set_01Z.append((Attr)) 333 | 334 | #------------------------------------------------------ 335 | for b in gotselected: 336 | 337 | Attrs = pm.xform('Get_Test_Mesh'+'.vtx['+b+']', q =True, ws = True, t=True)[x] 338 | 339 | set_02Z.append((Attrs)) 340 | 341 | pm.select(d =True) 342 | 343 | set_01ZMain.append(set_01Z) 344 | set_02ZMain.append(set_02Z) 345 | 346 | #---------------------------------------------------getDiff 347 | for o in range(len(gotselected)): 348 | 349 | x1 = float(set_01ZMain[0][o]) 350 | 351 | y1 = float(set_01ZMain[1][o]) 352 | 353 | z1 = float(set_01ZMain[2][o]) 354 | 355 | x2 = float(set_02ZMain[0][o]) 356 | 357 | y2 = float(set_02ZMain[1][o]) 358 | 359 | z2 = float(set_02ZMain[2][o]) 360 | 361 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 362 | 363 | finlDist.append(findis) 364 | 365 | #---------------------------------------------------percentage_find 366 | FinelWeight = [] 367 | 368 | for nnn in range(len(Value)): 369 | 370 | FinelW = (Value[nnn]/1.0)*finlDist[nnn] 371 | FinelWeight.append(FinelW) 372 | 373 | #---------------------------------------------------addSkin 374 | cmds.setAttr(unlockJnt[0]+'.liw', 0) 375 | for R in gotselected: 376 | 377 | 378 | if FinelWeight[gotselected.index(R)] != 0.0: 379 | 380 | 381 | 382 | cmds.skinPercent( SkinClustor(selecti_01)[0],selecti_01+'.vtx['+R+']', tv=(whichVer[0], FinelWeight[gotselected.index(R)])) 383 | 384 | 385 | cmds.delete('Get_Test_Mesh') 386 | 387 | for fv in Aljnts: 388 | cmds.setAttr(fv+'.liw', 0) 389 | 390 | cmds.skinCluster(SkinClustor(selecti_01)[0], e = True, ri= unlockJnt[0]) 391 | #---------------------------------------------------delete_Unwanted_Things 392 | if cluster_01no == []: 393 | pm.delete(unlockJnt[0]) 394 | pm.delete('CoolForge') 395 | pm.delete(selecti_00+'BaseWire') 396 | 397 | 398 | 399 | 400 | #---------------------------------------------------Total_Time 401 | 402 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 403 | 404 | #---------------------------------------------------end... 405 | 406 | 407 | 408 | 409 | 410 | '''-----------------------------------------------------------------------------------''' 411 | 412 | 413 | 414 | 415 | def ClusterConvert(): 416 | 417 | start_time = time.time() 418 | 419 | #=========================================Checking if defaut strings already Exists 420 | 421 | findString() 422 | 423 | #=========================================start 424 | 425 | selection0 = pm.ls(sl=True) 426 | positon = cmds.getAttr(selection0[0]+'.origin')[0] 427 | 428 | pm.select(d =True) 429 | 430 | 431 | #------------------------------------------------------Find_SkinCluster 432 | 433 | 434 | def SkinClustor(NamSkinClust): 435 | nodes = [] 436 | 437 | node = pm.listHistory(NamSkinClust) 438 | for damn in node: 439 | 440 | if pm.nodeType(damn) == 'skinCluster': 441 | nodes.append(damn) 442 | return nodes 443 | 444 | 445 | 446 | #------------------------------------------------------check if both have same skinclister 447 | 448 | 449 | if len(SkinClustor(selection0[-1]))==0: 450 | if pm.objExists("New_Vishu_Jnt") == False: 451 | pm.joint(n = "New_Vishu_Jnt") 452 | 453 | pm.skinCluster('New_Vishu_Jnt', selection0[-1]) 454 | 455 | 456 | #------------------------------------------------------Find_Hold_Jnt 457 | 458 | 459 | Meeshjnts = pm.skinCluster(selection0[-1], inf = True, q = True) 460 | 461 | pm.setAttr(Meeshjnts[0]+'.liw', 1) 462 | 463 | 464 | #------------------------------------------------------ 465 | pm.select(selection0[0], r =True) 466 | for nnn in range(len(selection0)-1): 467 | 468 | pm.select(selection0[nnn],add = True) 469 | 470 | 471 | pm.move( 1, y=True, r = True) 472 | 473 | pm.duplicate(selection0[-1], n = 'Get_Test_Mesh') 474 | 475 | pm.move( -1,y=True, r = True) 476 | 477 | pm.select(selection0[-1]) 478 | 479 | polyCount = pm.polyEvaluate( v=True ) 480 | 481 | 482 | #-----------------------------------------------------set1 483 | 484 | set_01ZMain = [] 485 | set_02ZMain = [] 486 | finlDist= [] 487 | 488 | for x in range(3): 489 | 490 | set_01Z = [] 491 | 492 | set_02Z = [] 493 | 494 | #------------------------------------------------------ 495 | for d in range(polyCount): 496 | 497 | Attr = '%.3f'%pm.xform(selection0[-1]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 498 | 499 | set_01Z.append((Attr)) 500 | 501 | #------------------------------------------------------ 502 | for b in range(polyCount): 503 | 504 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 505 | 506 | set_02Z.append((Attrs)) 507 | 508 | pm.select(d =True) 509 | 510 | set_01ZMain.append(set_01Z) 511 | set_02ZMain.append(set_02Z) 512 | 513 | #---------------------------------------------------getDiff 514 | for o in range(polyCount): 515 | 516 | x1 = float(set_01ZMain[0][o]) 517 | 518 | y1 = float(set_01ZMain[1][o]) 519 | 520 | z1 = float(set_01ZMain[2][o]) 521 | 522 | x2 = float(set_02ZMain[0][o]) 523 | 524 | y2 = float(set_02ZMain[1][o]) 525 | 526 | z2 = float(set_02ZMain[2][o]) 527 | 528 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 529 | 530 | finlDist.append(findis) 531 | 532 | 533 | #---------------------------------------------------addNewJnt and influnence 534 | 535 | if pm.objExists("NewVish_01_Jnt") == False: 536 | pm.joint(n = "NewVish_01_Jnt", p = positon) 537 | else: 538 | NewJnt(positon) 539 | 540 | NwJnt = pm.ls(sl=True) 541 | pm.select(selection0[-1]) 542 | 543 | pm.skinCluster(edit=True,ai= NwJnt[0],lw = 1) 544 | 545 | #---------------------------------------------------addSkin 546 | 547 | for R in range(polyCount): 548 | 549 | pm.setAttr(Meeshjnts[0]+'.liw', 0) 550 | 551 | 552 | 553 | if finlDist[R] != 0.0: 554 | 555 | 556 | 557 | pm.skinPercent( SkinClustor(selection0[-1])[0],selection0[-1]+'.vtx['+str(R)+']', tv=(NwJnt[0], finlDist[R])) 558 | 559 | 560 | pm.delete('Get_Test_Mesh') 561 | 562 | 563 | #---------------------------------------------------Total_Time 564 | 565 | 566 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 567 | 568 | 569 | 570 | 571 | #---------------------------------------------------end.. 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | '''-----------------------------------------------------------------------------------''' 580 | 581 | 582 | def SoftConvert(): 583 | 584 | start_time = time.time() 585 | 586 | #=========================================Checking if defaut strings already Exists 587 | 588 | findString() 589 | 590 | #=========================================start 591 | 592 | selection0 = cmds.ls(sl=True) 593 | selecti_00 = selection0[0] 594 | cmds.cluster(n = 'VishClust') 595 | 596 | shapename = cmds.listHistory(selecti_00)[0] 597 | positon = cmds.getAttr("VishClustHandleShape.origin")[0] 598 | cmds.delete('VishClust') 599 | 600 | cmds.select(shapename) 601 | cmds.pickWalk(d = 'up') 602 | 603 | transName = cmds.ls(sl=True) 604 | 605 | cmds.select(d =True) 606 | 607 | 608 | #------------------------------------------------------Find_SkinCluster 609 | 610 | 611 | def SkinClustor(NamSkinClust): 612 | nodes = [] 613 | 614 | node = cmds.listHistory(NamSkinClust) 615 | for damn in node: 616 | 617 | if cmds.nodeType(damn) == 'skinCluster': 618 | nodes.append(damn) 619 | return nodes 620 | 621 | cluster_01no = SkinClustor(transName) 622 | #------------------------------------------------------if_no_skin_on_mesh_thenadd_one_joint 623 | 624 | if cluster_01no == []: 625 | 626 | if cmds.objExists("New_VishHold_Jnt") == False: 627 | cmds.joint(n = "New_VishHold_Jnt") 628 | 629 | cmds.skinCluster('New_VishHold_Jnt', transName) 630 | 631 | 632 | cmds.select(d = True) 633 | cluster_01 = SkinClustor(transName) 634 | 635 | 636 | newJnt01 = [] 637 | 638 | if cmds.objExists("NewVish_01_Jnt") == True: 639 | cmds.select(d = True) 640 | NewJnt(positon) 641 | NwJnt = cmds.ls(sl=True) 642 | newJnt01.append(NwJnt[0]) 643 | cmds.select(transName) 644 | cmds.skinCluster(edit=True,ai=NwJnt[0],lw = 1, wt = 0) 645 | cmds.select(d = True) 646 | 647 | if cmds.objExists("NewVish_01_Jnt") == False: 648 | cmds.select(d = True) 649 | cmds.joint(n = "NewVish_01_Jnt", p = positon ) 650 | NwJnt = cmds.ls(sl=True) 651 | newJnt01.append(NwJnt[0]) 652 | cmds.select(transName) 653 | cmds.skinCluster(edit=True,ai="NewVish_01_Jnt",lw = 1, wt = 0) 654 | #------------------------------------------------------Find_Hold_Jnt 655 | 656 | 657 | Meeshjnts = cmds.skinCluster(transName, inf = True, q = True) 658 | 659 | cmds.setAttr(Meeshjnts[0]+'.liw', 1) 660 | 661 | 662 | #------------------------------------------------------ 663 | 664 | cmds.select(selecti_00, r =True) 665 | for nnn in range(len(selection0)): 666 | cmds.select(selection0[nnn],add = True) 667 | 668 | cmds.move( 1, y=True, r = True) 669 | 670 | cmds.duplicate(transName[0], n = 'Get_Test_Mesh') 671 | 672 | cmds.move( -1,y=True, r = True) 673 | 674 | cmds.select(transName[0]) 675 | 676 | polyCount = cmds.polyEvaluate( v=True ) 677 | 678 | 679 | #-----------------------------------------------------set1 680 | 681 | set_01ZMain = [] 682 | set_02ZMain = [] 683 | finlDist= [] 684 | 685 | for x in range(3): 686 | 687 | set_01Z = [] 688 | 689 | set_02Z = [] 690 | 691 | #------------------------------------------------------ 692 | for d in range(polyCount): 693 | 694 | Attr = '%.3f'%pm.xform(transName[0]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 695 | 696 | set_01Z.append((Attr)) 697 | 698 | #------------------------------------------------------ 699 | for b in range(polyCount): 700 | 701 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 702 | 703 | set_02Z.append((Attrs)) 704 | 705 | pm.select(d =True) 706 | 707 | set_01ZMain.append(set_01Z) 708 | set_02ZMain.append(set_02Z) 709 | 710 | #---------------------------------------------------getDiff 711 | for o in range(polyCount): 712 | 713 | x1 = float(set_01ZMain[0][o]) 714 | 715 | y1 = float(set_01ZMain[1][o]) 716 | 717 | z1 = float(set_01ZMain[2][o]) 718 | 719 | x2 = float(set_02ZMain[0][o]) 720 | 721 | y2 = float(set_02ZMain[1][o]) 722 | 723 | z2 = float(set_02ZMain[2][o]) 724 | 725 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 726 | 727 | finlDist.append(findis) 728 | 729 | 730 | #---------------------------------------------------addSkin 731 | 732 | for R in range(polyCount): 733 | 734 | cmds.setAttr(Meeshjnts[0]+'.liw', 0) 735 | 736 | 737 | 738 | if finlDist[R] != 0.0: 739 | 740 | 741 | 742 | cmds.skinPercent( SkinClustor(transName[0])[0],transName[0]+'.vtx['+str(R)+']', tv=(newJnt01[0], finlDist[R])) 743 | 744 | 745 | cmds.delete('Get_Test_Mesh') 746 | 747 | 748 | #---------------------------------------------------Total_Time 749 | 750 | 751 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 752 | 753 | 754 | 755 | 756 | #---------------------------------------------------end.. 757 | 758 | 759 | '''-----------------------------------------------------------------------------------''' 760 | 761 | 762 | def WrapCurveWireLatticeConvet(): 763 | 764 | start_time = time.time() 765 | 766 | #=========================================Checking if defaut strings already Exists 767 | 768 | findString() 769 | 770 | #=========================================start 771 | 772 | selection0 = cmds.ls(sl=True) 773 | 774 | cmds.select(d = True) 775 | 776 | #=========================================if_Wire_rotation_Zero 777 | def checkWire(NamwireDfm): 778 | nodes = [] 779 | 780 | node = cmds.listHistory(NamwireDfm) 781 | for damn in node: 782 | 783 | if cmds.nodeType(damn) == 'wire': 784 | nodes.append(damn) 785 | return nodes 786 | 787 | rotVal = [] 788 | if checkWire(selection0[1]) != []: 789 | rotVal2 = pm.getAttr(checkWire(selection0[1])[0]+".rotation") 790 | rotVal.append(rotVal2) 791 | if rotVal != 0.0: 792 | pm.setAttr(checkWire(selection0[1])[0]+".rotation", 0.0) 793 | 794 | #------------------------------------------------------Find_SkinCluster 795 | 796 | 797 | def SkinClustor(NamSkinClust): 798 | nodes = [] 799 | 800 | node = cmds.listHistory(NamSkinClust) 801 | for damn in node: 802 | 803 | if cmds.nodeType(damn) == 'skinCluster': 804 | nodes.append(damn) 805 | return nodes 806 | 807 | #------------------------------------------------------check if both have same skinclister 808 | meshClust = SkinClustor(selection0[1]) 809 | wireClust = SkinClustor(selection0[0]) 810 | 811 | if len(SkinClustor(selection0[0]))==0: 812 | print (pm.error( "<<<<<(no skin on wire)>>>>>" )) 813 | 814 | if len(SkinClustor(selection0[0]))==1: 815 | if wireClust[0] in meshClust: 816 | meshClust.remove(wireClust[0]) 817 | 818 | if SkinClustor(selection0[0]) != 0: 819 | for n in SkinClustor(selection0[0]): 820 | if n in meshClust: 821 | meshClust.remove(n) 822 | 823 | if meshClust==[]: 824 | if cmds.objExists("New_Vishu_Jnt") == False: 825 | cmds.joint(n = "New_Vishu_Jnt") 826 | 827 | cmds.skinCluster('New_Vishu_Jnt', selection0[1]) 828 | 829 | #------------------------------------------------------Find_Hold_Jnt 830 | 831 | 832 | Meeshjnts = cmds.skinCluster(selection0[1], inf = True, q = True) 833 | 834 | cmds.setAttr(Meeshjnts[0]+'.liw', 1) 835 | 836 | 837 | #------------------------------------------------------Find_deformer_Jnt 838 | 839 | 840 | Aljnts = cmds.skinCluster(selection0[0], inf = True, q = True) 841 | 842 | 843 | #------------------------------------------------------addInflunce_other_Jnts 844 | 845 | 846 | 847 | for gfs in Aljnts: 848 | 849 | if gfs not in Meeshjnts: 850 | 851 | cmds.select(selection0[1]) 852 | 853 | cmds.skinCluster(edit=True,ai=gfs,lw = 1) 854 | 855 | 856 | 857 | #------------------------------------------------------ 858 | 859 | 860 | for xx in Aljnts: 861 | 862 | whichVer = [] 863 | 864 | verName = cmds.select(xx, r =True) 865 | 866 | cmds.move( 1, xx+'.rotatePivot', y=True, r = True) 867 | 868 | whichVer.append(xx) 869 | 870 | cmds.select(selection0[1]) 871 | 872 | cmds.duplicate(n = 'Get_Test_Mesh') 873 | 874 | cmds.move( -1, xx+'.rotatePivot', y=True, r = True) 875 | 876 | cmds.select(selection0[1]) 877 | 878 | polyCount = cmds.polyEvaluate( v=True ) 879 | 880 | 881 | set_01ZMain = [] 882 | set_02ZMain = [] 883 | finlDist= [] 884 | 885 | for x in range(3): 886 | 887 | set_01Z = [] 888 | 889 | set_02Z = [] 890 | 891 | #------------------------------------------------------ 892 | for d in range(polyCount): 893 | 894 | Attr = '%.3f'%pm.xform(selection0[1]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 895 | 896 | set_01Z.append((Attr)) 897 | 898 | #------------------------------------------------------ 899 | for b in range(polyCount): 900 | 901 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 902 | 903 | set_02Z.append((Attrs)) 904 | 905 | pm.select(d =True) 906 | 907 | set_01ZMain.append(set_01Z) 908 | set_02ZMain.append(set_02Z) 909 | 910 | #---------------------------------------------------getDiff 911 | for o in range(polyCount): 912 | 913 | x1 = float(set_01ZMain[0][o]) 914 | 915 | y1 = float(set_01ZMain[1][o]) 916 | 917 | z1 = float(set_01ZMain[2][o]) 918 | 919 | x2 = float(set_02ZMain[0][o]) 920 | 921 | y2 = float(set_02ZMain[1][o]) 922 | 923 | z2 = float(set_02ZMain[2][o]) 924 | 925 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 926 | 927 | finlDist.append(findis) 928 | 929 | 930 | #---------------------------------------------------addSkin 931 | 932 | for R in range(int(polyCount)): 933 | 934 | cmds.setAttr(Meeshjnts[0]+'.liw', 0) 935 | 936 | 937 | 938 | if finlDist[R] != 0.0: 939 | 940 | 941 | 942 | cmds.skinPercent( SkinClustor(selection0[1])[0],selection0[1]+'.vtx['+str(R)+']', tv=(whichVer[0], finlDist[R])) 943 | 944 | 945 | cmds.delete('Get_Test_Mesh') 946 | 947 | 948 | if checkWire(selection0[1]) != []: 949 | pm.setAttr(checkWire(selection0[1])[0]+".rotation", rotVal[0]) 950 | #---------------------------------------------------Total_Time 951 | 952 | 953 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 954 | 955 | #---------------------------------------------------end.. 956 | 957 | 958 | 959 | 960 | 961 | '''---------------------------------------------------------------------------------''' 962 | def BlendShapeConvert(): 963 | 964 | start_time = time.time() 965 | 966 | #=========================================Checking if defaut strings already Exists 967 | 968 | findString() 969 | 970 | #=========================================start 971 | 972 | transName = pm.ls(sl=True) 973 | 974 | pm.listHistory(transName[0]) 975 | 976 | pm.select(d =True) 977 | 978 | #------------------------------------------------------Find_SkinCluster 979 | 980 | def BlendShape(NamBlensSHape): 981 | nodes = [] 982 | 983 | node = pm.listHistory(NamBlensSHape) 984 | for damn in node: 985 | 986 | if pm.nodeType(damn) == 'blendShape': 987 | nodes.append(damn) 988 | return nodes 989 | 990 | WeightName = pm.listAttr(BlendShape(transName[0])[0]+'.w', m =True) 991 | 992 | #------------------------------------------------------Find_SkinCluster 993 | 994 | 995 | def SkinClustor(NamSkinClust): 996 | nodes = [] 997 | 998 | node = pm.listHistory(NamSkinClust) 999 | for damn in node: 1000 | 1001 | if pm.nodeType(damn) == 'skinCluster': 1002 | nodes.append(damn) 1003 | return nodes 1004 | 1005 | #------------------------------------------------------check if both have same skinclister 1006 | 1007 | if len(SkinClustor(transName[0]))==0: 1008 | if pm.objExists("New_Vishu_Jnt") == False: 1009 | pm.joint(n = "New_Vishu_Jnt") 1010 | 1011 | pm.skinCluster('New_Vishu_Jnt', transName[0]) 1012 | 1013 | #------------------------------------------------------Find_Hold_Jnt 1014 | 1015 | MeshJnt = pm.skinCluster(transName[0], inf = True, q = True) 1016 | 1017 | pm.setAttr(MeshJnt[0]+'.liw', 1) 1018 | 1019 | #------------------------------------------------------ 1020 | 1021 | pm.setAttr(BlendShape(transName[0])[0]+'.'+WeightName[0], 1) 1022 | 1023 | pm.duplicate(transName[0], n = 'Get_Test_Mesh') 1024 | 1025 | pm.setAttr(BlendShape(transName[0])[0]+'.'+WeightName[0], 0) 1026 | 1027 | pm.select(transName[0]) 1028 | 1029 | polyCount = pm.polyEvaluate( v=True ) 1030 | 1031 | pm.select(d =True) 1032 | 1033 | #---------------------------------------------------addNewJnt and influnence 1034 | 1035 | if pm.objExists("NewVish_01_Jnt") == False: 1036 | pm.joint(n = "NewVish_01_Jnt") 1037 | else: 1038 | NewJnt((0.0,0.0,0.0)) 1039 | 1040 | NwJnt = pm.ls(sl=True) 1041 | pm.select(transName[0]) 1042 | 1043 | pm.skinCluster(edit=True,ai= NwJnt[0],lw = 1) 1044 | 1045 | #-----------------------------------------------------set1 1046 | 1047 | set_01ZMain = [] 1048 | set_02ZMain = [] 1049 | finlDist= [] 1050 | 1051 | 1052 | finlDistGetBig = [] 1053 | 1054 | 1055 | for x in range(3): 1056 | 1057 | set_01Z = [] 1058 | 1059 | set_02Z = [] 1060 | 1061 | #------------------------------------------------------ 1062 | for d in range(polyCount): 1063 | 1064 | Attr = '%.3f'%pm.xform(transName[0]+'.vtx['+str(d)+']', q =True, ws = True, t=True)[x] 1065 | 1066 | set_01Z.append((Attr)) 1067 | 1068 | #------------------------------------------------------ 1069 | for b in range(polyCount): 1070 | 1071 | Attrs = '%.3f'%pm.xform('Get_Test_Mesh'+'.vtx['+str(b)+']', q =True, ws = True, t=True)[x] 1072 | 1073 | set_02Z.append((Attrs)) 1074 | 1075 | pm.select(d =True) 1076 | 1077 | set_01ZMain.append(set_01Z) 1078 | set_02ZMain.append(set_02Z) 1079 | 1080 | #---------------------------------------------------getDiff 1081 | for o in range(polyCount): 1082 | 1083 | x1 = float(set_01ZMain[0][o]) 1084 | 1085 | y1 = float(set_01ZMain[1][o]) 1086 | 1087 | z1 = float(set_01ZMain[2][o]) 1088 | 1089 | x2 = float(set_02ZMain[0][o]) 1090 | 1091 | y2 = float(set_02ZMain[1][o]) 1092 | 1093 | z2 = float(set_02ZMain[2][o]) 1094 | 1095 | findis = math.sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2))) 1096 | 1097 | finlDist.append(findis) 1098 | finlDistGetBig.append(findis) 1099 | 1100 | #---------------------------------------------------addSkin 1101 | finlDistGetBig.sort() 1102 | finlDistGetBigNum = finlDistGetBig[-1] 1103 | 1104 | for R in range(polyCount): 1105 | 1106 | pm.setAttr(MeshJnt[0]+'.liw', 0) 1107 | 1108 | 1109 | if finlDist[R] != 0.0 : 1110 | 1111 | pm.skinPercent( SkinClustor(transName[0])[0],transName[0]+'.vtx['+str(R)+']', tv=(NwJnt[0], finlDist[R]/finlDistGetBigNum)) 1112 | 1113 | pm.delete('Get_Test_Mesh') 1114 | 1115 | #---------------------------------------------------Total_Time 1116 | 1117 | 1118 | sys.stdout.write('You have done a great job. ' " %s seconds " % (time.time() - start_time)) 1119 | 1120 | 1121 | 1122 | #---------------------------------------------------end.. 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | '''------------------------------------------------------------''' 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | #=========================================Lattice 1138 | def latticeButton(): 1139 | selectedo = cmds.ls(sl=True) 1140 | listo = cmds.listHistory(selectedo[1]) 1141 | allObjecto = [] 1142 | for s in listo: 1143 | if cmds.nodeType(s) == 'lattice': 1144 | allObjecto.append(s) 1145 | 1146 | if len(allObjecto) !=0: 1147 | WrapCurveWireLatticeConvet() 1148 | print('Lattice',allObjecto) 1149 | else: 1150 | cmds.error( "No_Lattice" ) 1151 | #========================================= 1152 | 1153 | #=========================================wire---- 1154 | def wireButton(): 1155 | selectedo = cmds.ls(sl=True) 1156 | listo = cmds.listHistory(selectedo[1]) 1157 | allObjecto = [] 1158 | for s in listo: 1159 | if cmds.nodeType(s) == 'wire': 1160 | allObjecto.append(s) 1161 | 1162 | if len(allObjecto) !=0: 1163 | WrapCurveWireLatticeConvet() 1164 | print('Wire',allObjecto) 1165 | else: 1166 | cmds.error( "No_Wire" ) 1167 | #========================================= 1168 | 1169 | #=========================================wrap---- 1170 | def wrapButton(): 1171 | selectedo = cmds.ls(sl=True) 1172 | listo = cmds.listHistory(selectedo[1]) 1173 | allObjecto = [] 1174 | for s in listo: 1175 | if cmds.nodeType(s) == 'wrap': 1176 | allObjecto.append(s) 1177 | 1178 | if len(allObjecto) !=0: 1179 | WrapCurveWireLatticeConvet() 1180 | print('Wrap',allObjecto) 1181 | else: 1182 | cmds.error( "No_Wrap" ) 1183 | #========================================= 1184 | 1185 | #=========================================blendShape---- 1186 | def blendShapeButton(): 1187 | selectedo = cmds.ls(sl=True) 1188 | listo = cmds.listHistory(selectedo[0]) 1189 | allObjecto = [] 1190 | for s in listo: 1191 | if cmds.nodeType(s) == 'blendShape': 1192 | allObjecto.append(s) 1193 | 1194 | if len(allObjecto) !=0: 1195 | BlendShapeConvert() 1196 | print('BlendShape',allObjecto) 1197 | else: 1198 | cmds.error( "No_BlendShape" ) 1199 | #========================================= 1200 | 1201 | #=========================================clusterHandle---- 1202 | def clusterButton(): 1203 | selectedo = cmds.ls(sl=True) 1204 | listo = cmds.listHistory(selectedo[-1]) 1205 | allObjecto = [] 1206 | for s in listo: 1207 | if cmds.nodeType(s) == 'cluster': 1208 | allObjecto.append(s) 1209 | 1210 | if len(allObjecto) !=0: 1211 | ClusterConvert() 1212 | print('Cluster',allObjecto) 1213 | else: 1214 | cmds.error( "No_Cluster" ) 1215 | #========================================= 1216 | 1217 | #=========================================SoftSelection 1218 | def SoftButton(): 1219 | checkSoft = cmds.softSelect(q = True, sse=True) 1220 | 1221 | selectedo = cmds.ls(sl=True) 1222 | 1223 | if cmds.nodeType(selectedo[0]) == 'mesh' and checkSoft == 1: 1224 | SoftConvert() 1225 | print('SoftSelection',selectedo) 1226 | else: 1227 | cmds.error( "No_SoftSelection" ) 1228 | 1229 | #========================================= 1230 | 1231 | #=========================================Curve 1232 | def CurveButton(): 1233 | pm.pickWalk(d = 'down') 1234 | selectedo = cmds.ls(sl=True) 1235 | pm.pickWalk(d = 'up') 1236 | if cmds.nodeType(selectedo[0]) == 'nurbsCurve' and cmds.nodeType(selectedo[1]) == 'mesh' : 1237 | SimpleCurveConvert() 1238 | print('Curve') 1239 | else: 1240 | cmds.error( "No_Curve" ) 1241 | #========================================= 1242 | 1243 | '''------------------------------------------------------------end''' 1244 | -------------------------------------------------------------------------------- /main/py2.py: -------------------------------------------------------------------------------- 1 | import maya.cmds as cmds 2 | import pymel.core as pm 3 | import sys 4 | import time 5 | import maya.OpenMaya as om 6 | import math 7 | 8 | 9 | ############################################### 10 | #Module 11 | ############################################### 12 | 13 | 14 | 15 | class utils: 16 | def __init__(self, object=None): 17 | self.obj = object 18 | 19 | def CreateCrv(self): 20 | crv = cmds.curve(p=[cmds.xform(d, t=1, q=1, ws=1) 21 | for d in cmds.ls(sl=1)]) 22 | cmds.setAttr(crv+".dispCV", 1) 23 | 24 | def softSelection(self): 25 | selection = om.MSelectionList() 26 | softSelection = om.MRichSelection() 27 | om.MGlobal.getRichSelection(softSelection) 28 | softSelection.getSelection(selection) 29 | 30 | dagPath = om.MDagPath() 31 | component = om.MObject() 32 | 33 | iter = om.MItSelectionList(selection, om.MFn.kMeshVertComponent) 34 | elements = [] 35 | while not iter.isDone(): 36 | iter.getDagPath(dagPath, component) 37 | dagPath.pop() 38 | fnComp = om.MFnSingleIndexedComponent(component) 39 | for i in range(fnComp.elementCount()): 40 | elements.append( 41 | [fnComp.element(i), fnComp.weight(i).influence()]) 42 | iter.next() 43 | return elements 44 | 45 | 46 | class getData: 47 | """ 48 | A class for extracting information and performing calculations related to deformations. 49 | """ 50 | 51 | def __init__(self, object=None): 52 | self.obj = object 53 | 54 | def get_skinCluster(self): 55 | """ 56 | Get the skinCluster associated with the object. 57 | 58 | Returns: 59 | skinCluster (str or None): The name of the skinCluster or None if not found. 60 | 61 | """ 62 | pyObj = pm.PyNode(self.obj) 63 | try: 64 | self.skn = pm.ls(pm.listHistory(pyObj), typ="skinCluster")[0] 65 | return self.skn 66 | 67 | except: 68 | return None 69 | 70 | def get_influnced_joints(self, skin_node=None): 71 | """ 72 | Get the list of influenced joints by a given skinCluster. 73 | 74 | Args: 75 | skin_node (str): The name of the skinCluster. 76 | 77 | Returns: 78 | influences (list or None): A list of influenced joint names or None if not found. 79 | 80 | """ 81 | try: 82 | self.influences = pm.skinCluster(skin_node, inf=True, q=True) 83 | return self.influences 84 | 85 | except: 86 | # pm.error('No skinCluster found!') 87 | pass 88 | 89 | def solvVert(self, vertcnt): 90 | """ 91 | Extract vertex numbers from vertex count strings. 92 | 93 | Args: 94 | vertcnt (list): List of vertex count strings. 95 | 96 | Returns: 97 | totalCounts (list): List of extracted vertex numbers as strings. 98 | 99 | """ 100 | totalCounts = [] 101 | 102 | for vert in vertcnt: 103 | split01 = vert.split("[") 104 | split02 = split01[-1].split("]") 105 | start = int(split02[0]) 106 | 107 | totalCounts.append(str(start)) 108 | 109 | return totalCounts 110 | 111 | def effectedVertNumber(self, meshClust, unlockJt): 112 | """ 113 | Calculate the affected vertex numbers when a joint is unlocked in a skinCluster. 114 | 115 | Args: 116 | meshClust (str): The name of the skinCluster. 117 | unlockJt (str): The name of the joint to be unlocked. 118 | 119 | Returns: 120 | vertNumb (list): List of affected vertex numbers as strings. 121 | 122 | """ 123 | vertNumb = [] 124 | pm.select(cl=1) 125 | pm.skinCluster(meshClust, e=True, siv=unlockJt) 126 | effectdVrt0 = cmds.ls(sl=True, fl=1) 127 | vertNumb = getData().solvVert(effectdVrt0) 128 | cmds.select(d=1) 129 | 130 | return vertNumb 131 | 132 | def getUnlockedJnt(self, mesh_joinds): 133 | """ 134 | Find and return joints that are unlocked among a list of joints. 135 | 136 | Args: 137 | mesh_joints (list): List of joint names to check. 138 | 139 | Returns: 140 | unlockJnd (list): List of unlocked joint names. 141 | 142 | Raises: 143 | pm.error: If no joint is unlocked or if more than one joint is unlocked. 144 | 145 | """ 146 | unlockJnd = [] 147 | for n in mesh_joinds: 148 | findlock = pm.getAttr(n + ".liw") 149 | if findlock == False: 150 | unlockJnd.append(n) 151 | 152 | if unlockJnd == []: 153 | pm.error("Please unlock one joint for distributing the weight") 154 | 155 | if len(unlockJnd) > 1: 156 | pm.error("Only one joint should be unlocked") 157 | 158 | return unlockJnd 159 | 160 | # ---------------------------------------------------Distance between two vertex 161 | 162 | def VertDistance(self, meshNam, VertNumList, moverNam, moveType=".rotatePivot", BS=False, WeightName=None): 163 | """ 164 | Calculate the distances between two sets of vertices on a mesh. 165 | 166 | Args: 167 | mesh_name (str): The name of the mesh. 168 | vert_num_list (list): List of vertex numbers as strings. 169 | mover_name (str): The name of the mover object. 170 | 171 | Returns: 172 | Distance (list): List of distances between vertices. 173 | 174 | """ 175 | old_PoseVert = [] 176 | New_PoseVert = [] 177 | Distance = [] 178 | 179 | for xyz in [0, 1, 2]: 180 | set_01Z = [] 181 | 182 | for d in VertNumList: 183 | Attr = pm.xform(meshNam + ".vtx[" + d + "]", q=True, ws=True, t=True)[ 184 | xyz 185 | ] 186 | 187 | set_01Z.append((Attr)) 188 | pm.select(d=True) 189 | 190 | old_PoseVert.append(set_01Z) 191 | 192 | if BS == False: 193 | pm.move(1, moverNam + moveType, y=True, r=True) 194 | else: 195 | pm.setAttr(moverNam[0] + '.' + WeightName[0], 0) 196 | 197 | for xyz in [0, 1, 2]: 198 | set_02Z = [] 199 | 200 | for b in VertNumList: 201 | Attrs = pm.xform(meshNam + ".vtx[" + b + "]", q=True, ws=True, t=True)[ 202 | xyz 203 | ] 204 | 205 | set_02Z.append((Attrs)) 206 | pm.select(d=True) 207 | 208 | New_PoseVert.append(set_02Z) 209 | 210 | if BS == False: 211 | pm.move(-1, moverNam + moveType, y=True, r=True) 212 | else: 213 | pm.setAttr(moverNam[0] + '.' + WeightName[0], 1) 214 | 215 | for o in range(len(VertNumList)): 216 | x1, y1, z1 = ( 217 | float(old_PoseVert[0][o]), 218 | float(old_PoseVert[1][o]), 219 | float(old_PoseVert[2][o]), 220 | ) 221 | x2, y2, z2 = ( 222 | float(New_PoseVert[0][o]), 223 | float(New_PoseVert[1][o]), 224 | float(New_PoseVert[2][o]), 225 | ) 226 | 227 | Distance.append( 228 | math.sqrt( 229 | ((x1 - x2) * (x1 - x2)) 230 | + ((y1 - y2) * (y1 - y2)) 231 | + ((z1 - z2) * (z1 - z2)) 232 | ) 233 | ) 234 | 235 | return Distance 236 | 237 | # ---------------------------------------------------percentage_find 238 | 239 | def WeightByOnePercentage(self, distance, hold_skin): 240 | """ 241 | Calculate weight values based on distances and skinCluster weights. 242 | 243 | Args: 244 | distance (list): List of distances between vertices. 245 | hold_skin (list): List of skinCluster weights. 246 | 247 | Returns: 248 | percentage (list): List of weight values. 249 | 250 | """ 251 | percentage = [] 252 | 253 | for nnn in range(len(hold_skin)): 254 | Onepercentage = (hold_skin[nnn] / 1.0) * distance[nnn] 255 | percentage.append(Onepercentage) 256 | 257 | return percentage 258 | 259 | # --------------------------------------------------- check deformer Type 260 | def deformerType(self, Name): 261 | """ 262 | Identify and return the type of deformer applied to an object. 263 | 264 | Args: 265 | name (str): The name of the object. 266 | 267 | Returns: 268 | deformer_type (str): The type of deformer (e.g., 'wire', 'lattice', 'cluster', 'wrap', 'blendShape'). 269 | 270 | """ 271 | nodes = [] 272 | 273 | for dfm in cmds.listHistory(Name): 274 | if cmds.nodeType(dfm) == "wire": 275 | pm.setAttr(dfm + ".rotation", 0.0) 276 | nodes.append("wire") 277 | if cmds.nodeType(dfm) == "lattice": 278 | nodes.append("lattice") 279 | if cmds.nodeType(dfm) == "cluster": 280 | nodes.append("cluster") 281 | if cmds.nodeType(dfm) == "wrap": 282 | nodes.append("wrap") 283 | if cmds.nodeType(dfm) == "blendShape": 284 | nodes.append("blendShape") 285 | if cmds.nodeType(dfm) == "deltaMesh": 286 | nodes.append("deltaMesh") 287 | 288 | return nodes[0] 289 | 290 | def NewJnt(self, positonN, MeshNam): 291 | cmds.select(d=True) 292 | objList = cmds.ls(MeshNam + "_*_Jnt") 293 | number = [int(i.split("_")[1]) for i in objList] 294 | 295 | nList = [] 296 | for i in range(1, len(number)+2): 297 | if i not in number: 298 | nList.append(i) 299 | 300 | jntt = cmds.joint(n=MeshNam + "_" + 301 | str(nList[0]).zfill(3) + "_Jnt", p=positonN) 302 | cmds.select(d=True) 303 | return jntt 304 | 305 | def BlendShape(self, Nam): 306 | 307 | list = cmds.listHistory(Nam, lv=1) 308 | nodes = [i for i in list if pm.nodeType(i) == 'blendShape'] 309 | return nodes 310 | 311 | def check_connections(self, obj): 312 | attributes = ['tx', 'ty', 'tz', 313 | 'rx', 'ry', 'rz', 314 | 'sx', 'sy', 'sz'] 315 | 316 | for i in attributes: 317 | keys = cmds.keyframe(obj + '.' + i, query=True) 318 | if keys: 319 | print('Please remove all keyframes on joints') 320 | 321 | '''constraints = cmds.listConnections(obj + '.' + i, type='constraint') 322 | if constraints: 323 | print('Please remove all constraints on joints') 324 | 325 | connections = cmds.listConnections(obj + '.' + i, plugs=True) 326 | if connections: 327 | print('Please remove all connections on joints')''' 328 | 329 | 330 | class deformerConvert(getData): 331 | """ 332 | Main class for converting deformers to skincluster. 333 | 334 | Args: 335 | deformer (str, optional): The name of the deformer to be converted. 336 | mesh (str, optional): The name of the mesh to be processed. 337 | 338 | Attributes: 339 | deformer (str): The name of the deformer being converted. 340 | mesh (str): The name of the mesh being processed. 341 | hold_joint (str or None): The name of the hold joint created or None. 342 | meshCluster (str or None): The name of the mesh's skinCluster or None. 343 | vertNumber (list): List of vertex numbers as strings. 344 | hold_skin_value (list): List of hold joint's skin weights. 345 | deformer_inf_jnts (list): List of influenced joint names from the deformer. 346 | mesh_inf_jnts (list): List of influenced joint names from the mesh. 347 | 348 | """ 349 | 350 | def __init__(self, deformer=None, mesh=None): 351 | getData.__init__(self) 352 | self.deformer = deformer 353 | self.mesh = mesh 354 | self.meshCluster = None 355 | self.vertNumber = [] 356 | self.hold_skin_value = [] 357 | self.deformer_inf_jnts = getData().get_influnced_joints(self.deformer) 358 | self.Mesh_inf_jnts = getData().get_influnced_joints(self.mesh) 359 | self.NewjntNam = None 360 | self.hold_jntSuffix = '_hold_jnt' 361 | self.dupMesh = None 362 | 363 | def deformer_skin_convert(self): 364 | """ 365 | Convert skin weights from the deformer to the mesh. 366 | 367 | Use For Curve to Skin 368 | 369 | """ 370 | # get mesh skin cluster 371 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 372 | 373 | # check if there is a cluster else create a new one 374 | if self.meshCluster == None: 375 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 376 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 377 | 378 | self.meshCluster = pm.skinCluster( 379 | self.mesh + self.hold_jntSuffix, self.mesh) 380 | cmds.select(cl=1) 381 | 382 | # get influnced joints of the mesh 383 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 384 | 385 | # get unlocked joint to transfer deformer weight 386 | unlockJnt = getData().getUnlockedJnt(mesh_joints) 387 | 388 | # lock all other weights except the first unlocked weight 389 | pm.setAttr(unlockJnt[0] + ".liw", 1) 390 | 391 | # get effected verticies 392 | self.vertNumber = getData().effectedVertNumber(self.meshCluster, unlockJnt) 393 | 394 | # save hold joint's weight 395 | for fdf in self.vertNumber: 396 | JntVal = pm.skinPercent( 397 | str(self.meshCluster), 398 | self.mesh + ".vtx[" + fdf + "]", 399 | transform=unlockJnt[0], 400 | query=True, 401 | ) 402 | self.hold_skin_value.append(JntVal) 403 | 404 | # Add other joints to skin cluster 405 | for gfs in self.deformer_inf_jnts: 406 | pm.skinCluster(self.meshCluster, edit=True, ai=gfs, lw=1) 407 | 408 | # Create wire deformer 409 | wireDfm = pm.wire( 410 | self.mesh, 411 | w=self.deformer, 412 | gw=False, 413 | en=1.000000, 414 | ce=0.000000, 415 | li=0.000000, 416 | dds=[(0, 1000)], 417 | )[0] 418 | pm.setAttr(wireDfm.rotation, 0) 419 | 420 | for xx in self.deformer_inf_jnts: 421 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 422 | WeightbyPercent = getData().WeightByOnePercentage( 423 | Fineldistance, self.hold_skin_value 424 | ) 425 | 426 | # apply skin weight 427 | cmds.setAttr(unlockJnt[0] + ".liw", 0) 428 | for R in self.vertNumber: 429 | if WeightbyPercent[self.vertNumber.index(R)] != 0.0: 430 | pm.skinPercent( 431 | self.meshCluster, 432 | self.mesh + ".vtx[" + R + "]", 433 | tv=(xx, WeightbyPercent[self.vertNumber.index(R)]), 434 | ) 435 | 436 | for fv in self.deformer_inf_jnts: 437 | pm.setAttr(fv + ".liw", 0) 438 | 439 | pm.skinCluster(self.meshCluster, e=True, ri=unlockJnt[0]) 440 | 441 | # cleanup 442 | if self.meshCluster == []: 443 | pm.delete(unlockJnt[0]) 444 | 445 | pm.disconnectAttr((cmds.listRelatives(self.deformer, shapes=True)[ 446 | 0])+".worldSpace[0]", wireDfm+".deformedWire[0]") 447 | pm.delete(wireDfm) 448 | pm.delete(self.deformer + "BaseWire") 449 | 450 | def rest_deformer_skin_convert(self): 451 | """ 452 | Restore the original skin weights on the mesh after deformer conversion. 453 | 454 | Use for Wire, Wrap, delta Mesh and Lattice 455 | 456 | """ 457 | 458 | # to check type of deformer and set wire rotation 1 459 | getData().deformerType(self.mesh) 460 | 461 | meshSkinClust = [getData(object=self.mesh).get_skinCluster()] 462 | 463 | deformerSkinClust = getData(object=self.deformer).get_skinCluster() 464 | 465 | if not deformerSkinClust: # error if no skin 466 | pm.error("<<<<<(No SKIN found on deformer)>>>>>") 467 | 468 | if deformerSkinClust in meshSkinClust: # reomve if same skincluster in mesh 469 | meshSkinClust.remove(deformerSkinClust) 470 | 471 | # check if there is a cluster else create a new one 472 | if self.meshCluster == None: 473 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 474 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 475 | 476 | self.meshCluster = pm.skinCluster( 477 | self.mesh + self.hold_jntSuffix, self.mesh) 478 | cmds.select(cl=1) 479 | 480 | # get effected verticies 481 | self.vertNumber = [str(i) for i in range( 482 | cmds.polyEvaluate(self.mesh, v=True))] 483 | 484 | # Add other joints to skin cluster 485 | pm.skinCluster(self.meshCluster, 486 | ai=self.deformer_inf_jnts, edit=True, lw=1, wt=0) 487 | 488 | for xx in self.deformer_inf_jnts: 489 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 490 | 491 | # skin apply 492 | for R in self.vertNumber: 493 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 494 | pm.skinPercent( 495 | self.meshCluster, 496 | self.mesh + ".vtx[" + R + "]", 497 | tv=(xx, Fineldistance[self.vertNumber.index(R)]), 498 | ) 499 | 500 | for fv in self.deformer_inf_jnts: 501 | pm.setAttr(fv + ".liw", 0) 502 | 503 | def SoftSelectionToConvert(self): 504 | sel = cmds.ls(sl=True) 505 | 506 | cmds.select(d=1) 507 | 508 | bbx = cmds.xform(sel, q=True, bb=True, ws=True) 509 | 510 | positon = ( 511 | ((bbx[0] + bbx[3]) / 2.0), 512 | ((bbx[1] + bbx[4]) / 2.0), 513 | ((bbx[2] + bbx[5]) / 2.0), 514 | ) 515 | 516 | self.mesh = sel[0].split(".")[0] 517 | 518 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 519 | 520 | # check if there is a cluster else create a new one 521 | if self.meshCluster == None: 522 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 523 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 524 | 525 | self.meshCluster = pm.skinCluster( 526 | self.mesh + self.hold_jntSuffix, self.mesh) 527 | cmds.select(cl=1) 528 | 529 | # get influnced joints of the mesh 530 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 531 | 532 | # get unlocked joint to transfer deformer weight 533 | unlockJnt = getData().getUnlockedJnt(mesh_joints) 534 | 535 | self.vertNumber = getData().effectedVertNumber(self.meshCluster, unlockJnt) 536 | 537 | # Add new joints to skin cluster 538 | if cmds.objExists(self.mesh + "_001_Jnt") == False: 539 | self.NewjntNam = cmds.joint(n=self.mesh + "_001_Jnt", p=positon) 540 | cmds.skinCluster(self.mesh, edit=True, 541 | ai=self.NewjntNam, lw=1, wt=0) 542 | else: 543 | self.NewjntNam = getData().NewJnt(positon, self.mesh) 544 | cmds.skinCluster(self.mesh, edit=True, 545 | ai=self.NewjntNam, lw=1, wt=0) 546 | 547 | cmds.select(sel) 548 | for i in utils().softSelection(): 549 | cmds.select(d=1) 550 | 551 | pm.skinPercent( 552 | self.meshCluster, 553 | self.mesh + ".vtx[" + str(i[0]) + "]", 554 | tv=(self.NewjntNam, i[1]), 555 | ) 556 | 557 | def ClusterConvert(self): 558 | 559 | positon = cmds.getAttr(self.deformer+'.origin')[0] 560 | cmds.select(d=True) 561 | 562 | clust = getData(object=self.mesh).get_skinCluster() 563 | 564 | if clust == None: 565 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 566 | pm.joint(n=self.mesh + self.hold_jntSuffix) 567 | 568 | pm.skinCluster(self.mesh + self.hold_jntSuffix, self.mesh) 569 | 570 | mesh_joints = pm.skinCluster(self.mesh, inf=True, q=True) 571 | # pm.setAttr(mesh_joints[0]+'.liw', 1) 572 | 573 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 574 | 575 | # get effected verticies 576 | self.vertNumber = getData().effectedVertNumber( 577 | self.meshCluster, self.mesh + self.hold_jntSuffix) 578 | 579 | Fineldistance = getData().VertDistance( 580 | self.mesh, self.vertNumber, self.deformer, moveType="") 581 | 582 | if pm.objExists(self.mesh + "_001_Jnt") == False: 583 | self.NewjntNam = cmds.joint(n=self.mesh + "_001_Jnt", p=positon) 584 | cmds.skinCluster(self.mesh, edit=True, 585 | ai=self.NewjntNam, lw=1, wt=0) 586 | else: 587 | self.NewjntNam = getData().NewJnt(positon, self.mesh) 588 | cmds.skinCluster(self.mesh, edit=True, 589 | ai=self.NewjntNam, lw=1, wt=0) 590 | 591 | # skin apply 592 | for R in self.vertNumber: 593 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 594 | pm.skinPercent( 595 | self.meshCluster, 596 | self.mesh + ".vtx[" + R + "]", 597 | tv=(self.NewjntNam, 598 | Fineldistance[self.vertNumber.index(R)]), 599 | ) 600 | 601 | def blendShapeConvert(self): 602 | 603 | self.deformer = getData().BlendShape(self.mesh) 604 | 605 | WeightNam = pm.listAttr(self.deformer[0] + '.w', m=True) 606 | 607 | clust = getData(object=self.mesh).get_skinCluster() 608 | 609 | if clust == None: 610 | cmds.select(d=1) 611 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 612 | pm.joint(n=self.mesh + self.hold_jntSuffix) 613 | 614 | pm.skinCluster(self.mesh + self.hold_jntSuffix, self.mesh) 615 | 616 | pm.setAttr(self.deformer[0] + '.' + WeightNam[0], 1) 617 | 618 | self.meshCluster = getData(object=self.mesh).get_skinCluster() 619 | 620 | self.vertNumber = getData().effectedVertNumber( 621 | self.meshCluster, self.mesh + self.hold_jntSuffix) 622 | 623 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, 624 | self.deformer, moveType="", BS=True, WeightName=WeightNam) 625 | 626 | if pm.objExists(self.mesh + "_001_Jnt") == False: 627 | self.NewjntNam = cmds.joint(n=self.mesh + "_001_Jnt", p=(0, 0, 0)) 628 | cmds.skinCluster(self.mesh, edit=True, 629 | ai=self.NewjntNam, lw=1, wt=0) 630 | else: 631 | self.NewjntNam = getData().NewJnt((0, 0, 0), self.mesh) 632 | cmds.skinCluster(self.mesh, edit=True, 633 | ai=self.NewjntNam, lw=1, wt=0) 634 | 635 | # skin apply 636 | for R in self.vertNumber: 637 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 638 | pm.skinPercent( 639 | self.meshCluster, 640 | self.mesh + ".vtx[" + R + "]", 641 | tv=(self.NewjntNam, 642 | Fineldistance[self.vertNumber.index(R)]), 643 | ) 644 | 645 | def deltaMush_skin_convert(self): 646 | """ 647 | Restore the original skin weights on the mesh after deformer conversion. 648 | 649 | Use for Wire, Wrap, delta Mesh and Lattice 650 | 651 | """ 652 | # print (self.Mesh_inf_jnts) 653 | # getData().check_connections(self.Mesh_inf_jnts) 654 | 655 | self.dupMesh = cmds.duplicate(self.mesh, n=self.mesh+"_Test")[0] 656 | 657 | meshSkinClust = [getData(object=self.mesh).get_skinCluster()] 658 | 659 | if not meshSkinClust: # error if no skin 660 | pm.error("<<<<<(No SKIN found on mesh)>>>>>") 661 | 662 | # check if there is a cluster else create a new one 663 | if self.meshCluster == None: 664 | if pm.objExists(self.mesh + self.hold_jntSuffix) == False: 665 | pm.createNode("joint", n=self.mesh + self.hold_jntSuffix) 666 | 667 | pm.skinCluster( 668 | meshSkinClust[0], ai=self.mesh + self.hold_jntSuffix, edit=True, lw=0, wt=0) 669 | 670 | # get effected verticies 671 | self.vertNumber = [str(i) for i in range( 672 | cmds.polyEvaluate(self.mesh, v=True))] 673 | 674 | # Add all joints to skin cluster with dupMesh 675 | self.meshCluster = pm.skinCluster(self.Mesh_inf_jnts, self.dupMesh) 676 | cmds.select(cl=1) 677 | pm.skinCluster(self.meshCluster, ai=self.mesh + 678 | self.hold_jntSuffix, edit=True, lw=0, wt=0) 679 | 680 | for xx in self.Mesh_inf_jnts: 681 | Fineldistance = getData().VertDistance(self.mesh, self.vertNumber, xx) 682 | 683 | # skin apply 684 | for R in self.vertNumber: 685 | if Fineldistance[self.vertNumber.index(R)] != 0.0: 686 | pm.skinPercent( 687 | self.meshCluster, 688 | self.dupMesh + ".vtx[" + R + "]", 689 | tv=(xx, Fineldistance[self.vertNumber.index(R)]), 690 | ) 691 | 692 | for fv in self.Mesh_inf_jnts: 693 | pm.setAttr(fv + ".liw", 0) 694 | 695 | # copyWeight from dup mesh to main mesh 696 | cmds.connectAttr(self.meshCluster + ".weightList", 697 | meshSkinClust[0].name() + ".weightList",) 698 | cmds.disconnectAttr(self.meshCluster + ".weightList", 699 | meshSkinClust[0].name() + ".weightList",) 700 | cmds.delete(self.dupMesh, self.mesh + self.hold_jntSuffix) 701 | 702 | # TODO "error, 'only one joint' " softseletion convert, when other joint are unlocked, maybe it 703 | # should give error 704 | 705 | # deltaMush working with heirarchy, but there should not be any key (add error) 706 | 707 | 708 | 709 | 710 | 711 | 712 | ############################################### 713 | #Transform 714 | ############################################### 715 | 716 | 717 | class JointProc: 718 | import pymel.core as pm 719 | 720 | cmdsSel = None 721 | sel = None 722 | 723 | def __init__(self): 724 | self.sel = pm.ls(sl=1) 725 | 726 | def getSelection(self, Pivs=cmdsSel): 727 | components = Pivs 728 | selList = [] 729 | objName = components[0][0 : components[0].index(".")] 730 | # go through every component in the list. If it is a single component ("pCube1.vtx[1]"), add it to the list. Else, 731 | # add each component in the index ("pCube1.vtx[1:5]") to the list 732 | for c in components: 733 | if ":" not in c: 734 | selList.append(c) 735 | else: 736 | startComponent = int(c[c.index("[") + 1 : c.index(":")]) 737 | endComponent = int(c[c.index(":") + 1 : c.index("]")]) 738 | componentType = c[c.index(".") + 1 : c.index("[")] 739 | while startComponent <= endComponent: 740 | selList.append( 741 | objName + "." + componentType + "[" + str(startComponent) + "]" 742 | ) 743 | startComponent += 1 744 | 745 | return selList 746 | pivsList.append(selList) 747 | 748 | def CtrJnt(self, Piv=sel): 749 | # createJoint 750 | 751 | sl = Piv 752 | try: 753 | pm.select(sl) 754 | tempPos = pm.cluster(n="Temp")[1] 755 | Jnt = pm.createNode("joint", n=(sl[0] + "Jnt")) 756 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 757 | pm.delete(tempPos) 758 | return Jnt 759 | 760 | except: 761 | tempPos = pm.createNode("transform", n="Temp") 762 | pm.delete(pm.parentConstraint(sl, tempPos)) 763 | Jnt = pm.createNode("joint", n=(sl[0] + "_Jnt")) 764 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 765 | pm.delete(tempPos) 766 | return Jnt 767 | 768 | def CtrJntEach(self, cmdsSel=None): 769 | # createJoint 770 | try: 771 | sl = getSelection() 772 | print(sl) 773 | 774 | except: 775 | sl = cmdsSel 776 | print(sl) 777 | 778 | jnts_tr = [] 779 | for i in sl: 780 | pass 781 | if pm.objectType(i) == "mesh": 782 | try: 783 | pm.select(i) 784 | tempPos = pm.cluster(n="Temp")[1] 785 | Jnt = pm.createNode("joint", n=(i + "Jnt")) 786 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 787 | pm.delete(tempPos) 788 | print(Jnt) 789 | 790 | except: 791 | tempPos = pm.createNode("transform", n="Temp") 792 | pm.delete(pm.parentConstraint(i, tempPos)) 793 | Jnt = pm.createNode("joint", n=(i + "_Jnt")) 794 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 795 | pm.delete(tempPos) 796 | print(Jnt) 797 | else: 798 | pm.select(i) 799 | tempPos = pm.cluster(n="Temp")[1] 800 | Jnt = pm.createNode("joint", n=(i + "Jnt")) 801 | pm.delete(pm.parentConstraint(tempPos, Jnt)) 802 | pm.delete(tempPos) 803 | print(Jnt) 804 | 805 | def transfroms_to_curve(self, cmdsSel=None): 806 | p = [] 807 | trs = cmdsSel 808 | for i in trs: 809 | mtx = i.worldMatrix.get() 810 | tr = mtx.translate.get() 811 | p.append(tr) 812 | crv = pm.curve(d=3, p=p) 813 | 814 | 815 | 816 | 817 | 818 | ######################################### 819 | #UI 820 | ######################################### 821 | 822 | # window 823 | win_name = "vn_skin_tools" 824 | win_title = "VN Skin Tools" 825 | win_size = (330, 290) 826 | if pm.window(win_name, q=1, exists=True): 827 | pm.deleteUI(win_name, window=True) 828 | 829 | """ 830 | if pm.windowPref(win_name,q=1 ,exists=True ): 831 | pm.windowPref(win_name, r=0 ) 832 | """ 833 | pm.window( 834 | win_name, 835 | title=win_title, 836 | widthHeight=win_size, 837 | sizeable=False, 838 | bgc=[(0.2), (0.2), (0.2)], 839 | ) 840 | 841 | Tab = pm.tabLayout("Tabs", p=win_name, tc=0, stb=1, snt=0) 842 | 843 | deformer_form = pm.formLayout("Converter", parent="Tabs") 844 | skin_utils_form = pm.formLayout("Import/Export", en=0, vis=0) 845 | utils_form = pm.formLayout("Utilities", parent="Tabs") 846 | about_form = pm.formLayout("About", parent="Tabs") 847 | 848 | # output_win_frame = pm.formLayout("MirrorWeights", parent="Tabs") 849 | 850 | 851 | radio_layout = pm.rowColumnLayout(nc=2, p=deformer_form, cal=[2, "left"], h=55) 852 | radio_coll = pm.radioCollection(parent=radio_layout) 853 | crv_to_skn_btn = pm.radioButton( 854 | "crv_skn_rb", l="Curve To Skin", p=radio_layout, sl=1, cc="crv_skn_cc()" 855 | ) 856 | softsel_to_skn = pm.radioButton( 857 | "softsel_skn_rb", l="Soft Selection To Skin", p=radio_layout, cc="softSel_skn_cc()" 858 | ) 859 | cluster_to_skn = pm.radioButton( 860 | "cls_skn_rb", l="Cluster To Skin", p=radio_layout, cc="cl_skn_cc()" 861 | ) 862 | df_to_skn_btn = pm.radioButton( 863 | "restdf_skn_rb", l="Wire/Wrap/Lattice", p=radio_layout, cc="df_skn_cc()" 864 | ) # /DeltaMush 865 | blendshape_to_skn = pm.radioButton( 866 | "bs_skn_rb", l="Blendshape To Skin", cc="blend_to_skin_cc()", p=radio_layout 867 | ) 868 | 869 | blocking_to_skin = pm.radioButton( 870 | "smooth_skn_rb", 871 | l="Blocking to Smooth Skin", 872 | cc="delta_to_skin_cc()", 873 | p=radio_layout, 874 | ) 875 | 876 | informatipn_txt_f = pm.textField( 877 | "info_txtf", 878 | w=180, 879 | h=25, 880 | p=deformer_form, 881 | en=0, 882 | pht="Add a Skinned Curve and Mesh", 883 | nbg=1, 884 | ) 885 | 886 | mesh_textfield = pm.textField( 887 | "mesh_field", w=180, h=35, pht="Add Mesh", p=deformer_form 888 | ) 889 | deformer_textfield = pm.textField( 890 | "df_field", w=180, h=35, pht="Add Skinned Curve", p=deformer_form 891 | ) 892 | 893 | 894 | add_mesh_btn = pm.button( 895 | "mesh_btn", l="Select Mesh", p=deformer_form, w=120, h=34, c="mesh_add()" 896 | ) 897 | add_df_btn = pm.button( 898 | "df_btn", l="Select Deformer", p=deformer_form, w=120, h=34, c="deformer_add()" 899 | ) 900 | convert_btn = pm.iconTextButton( 901 | "cvt_btn", 902 | style="iconAndTextHorizontal", 903 | image1="polyColorSetEditor.png", 904 | label="Convert to Skin", 905 | p=deformer_form, 906 | w=130, 907 | h=40, 908 | bgc=[(0.33), (0.33), (0.353)], 909 | c="convert_to_skin()", 910 | ) 911 | time_elapsed_txf = pm.textField( 912 | "time_txtf", 913 | w=80, 914 | h=25, 915 | p=deformer_form, 916 | en=0, 917 | pht="Time Elapsed: ", 918 | nbg=1, 919 | ) 920 | 921 | pm.formLayout( 922 | deformer_form, 923 | e=1, 924 | attachForm=[ 925 | (radio_layout, "top", 10), 926 | (informatipn_txt_f, "top", 67), 927 | (mesh_textfield, "top", 97), 928 | (deformer_textfield, "top", 135), 929 | (add_mesh_btn, "top", 98), 930 | (add_df_btn, "top", 136), 931 | (time_elapsed_txf, "top", 235), 932 | (convert_btn, "top", 190), 933 | (informatipn_txt_f, "left", 10), 934 | (radio_layout, "left", 10), 935 | (mesh_textfield, "left", 10), 936 | (deformer_textfield, "left", 10), 937 | (time_elapsed_txf, "left", 90), 938 | (convert_btn, "left", 95), 939 | (informatipn_txt_f, "right", 10), 940 | (add_mesh_btn, "right", 10), 941 | (add_df_btn, "right", 10), 942 | (time_elapsed_txf, "right", 50), 943 | ], 944 | ) 945 | 946 | skinCLusterName = pm.scrollField( 947 | "skn_cl_name", 948 | w=300, 949 | h=30, 950 | p=skin_utils_form, 951 | bgc=[(0.17), (0.18), (0.19)], 952 | editable=True, 953 | wordWrap=False, 954 | ) 955 | selc_mesh_btn = pm.button( 956 | "select_mesh", 957 | l="1. Select Mesh", 958 | p=skin_utils_form, 959 | w=150, 960 | h=30, 961 | bgc=[(0.2), (0.2), (0.2)], 962 | en=1, 963 | ) 964 | rename_skn_btn = pm.button( 965 | "rename_skn", 966 | l="2. Rename SkinC", 967 | p=skin_utils_form, 968 | w=150, 969 | h=30, 970 | bgc=[(0.2), (0.2), (0.2)], 971 | en=1, 972 | ) 973 | 974 | path_textfield = pm.textField( 975 | "df_field", 976 | w=180, 977 | h=41, 978 | pht="Add Deformer", 979 | p=skin_utils_form, 980 | bgc=[(0.17), (0.18), (0.19)], 981 | ) 982 | selectPath_button = pm.iconTextButton( 983 | "df_btn", 984 | style="iconAndTextHorizontal", 985 | l="Select path", 986 | p=skin_utils_form, 987 | w=120, 988 | h=40, 989 | bgc=[(0.2), (0.2), (0.2)], 990 | en=1, 991 | ) 992 | 993 | import_skn_button = pm.iconTextButton( 994 | "imp_skn", 995 | style="iconAndTextHorizontal", 996 | l="Import Deformer", 997 | p=skin_utils_form, 998 | w=150, 999 | h=40, 1000 | bgc=[(0.2), (0.2), (0.2)], 1001 | en=1, 1002 | ) 1003 | export_skn_button = pm.iconTextButton( 1004 | "exp_skn ", 1005 | style="iconAndTextHorizontal", 1006 | l="Export Deformer", 1007 | p=skin_utils_form, 1008 | w=150, 1009 | h=40, 1010 | bgc=[(0.2), (0.2), (0.2)], 1011 | en=1, 1012 | ) 1013 | 1014 | pm.formLayout( 1015 | skin_utils_form, 1016 | e=1, 1017 | attachForm=[ 1018 | (skinCLusterName, "top", 10), 1019 | (selc_mesh_btn, "top", 45), 1020 | (rename_skn_btn, "top", 45), 1021 | (import_skn_button, "top", 125), 1022 | (export_skn_button, "top", 125), 1023 | (path_textfield, "top", 80), 1024 | (selectPath_button, "top", 80), 1025 | (path_textfield, "left", 10), 1026 | (skinCLusterName, "left", 10), 1027 | (import_skn_button, "left", 11), 1028 | (selc_mesh_btn, "left", 11), 1029 | (rename_skn_btn, "right", 11), 1030 | (selectPath_button, "right", 10), 1031 | (export_skn_button, "right", 10), 1032 | ], 1033 | ) 1034 | 1035 | jnt_btwn_btn = pm.button( 1036 | "jnt_btwn_btn", 1037 | l="Joint at Center", 1038 | p=utils_form, 1039 | w=290, 1040 | h=50, 1041 | bgc=[(0.2), (0.21), (0.2)], 1042 | en=1, 1043 | c="jnt_btwn()", 1044 | ) 1045 | jnt_each_btn = pm.button( 1046 | "jnt_each_btn", 1047 | l="Joint at each selection (Supports Mesh)", 1048 | p=utils_form, 1049 | w=290, 1050 | h=50, 1051 | bgc=[(0.2), (0.21), (0.2)], 1052 | en=1, 1053 | c="jnt_each()", 1054 | ) 1055 | tr_to_crv_btn = pm.button( 1056 | "tr_to_crv_btn", 1057 | l="Transfrom to Curve", 1058 | p=utils_form, 1059 | w=290, 1060 | h=50, 1061 | bgc=[(0.2), (0.21), (0.2)], 1062 | en=1, 1063 | c="tr_crv()", 1064 | ) 1065 | pm.formLayout( 1066 | utils_form, 1067 | e=1, 1068 | attachForm=[ 1069 | (jnt_btwn_btn, "top", 10), 1070 | (jnt_each_btn, "top", 69), 1071 | (tr_to_crv_btn, "top", 130), 1072 | (jnt_btwn_btn, "left", 10), 1073 | (jnt_each_btn, "left", 10), 1074 | (tr_to_crv_btn, "left", 10), 1075 | (jnt_btwn_btn, "right", 10), 1076 | (jnt_each_btn, "right", 10), 1077 | (tr_to_crv_btn, "right", 10), 1078 | ], 1079 | ) 1080 | about_txf = pm.button( 1081 | "about_txf", 1082 | w=290, 1083 | h=50, 1084 | l="Authors:\nVishal Nagpal\nSiddarth Mehra", 1085 | p=about_form, 1086 | en=1, 1087 | bgc=[0.5, 0.7, 0.7], 1088 | c="pm.launch(web='https://www.linkedin.com/in/vishal-nagpal-82975a149/')", 1089 | ) 1090 | link_btnSid = pm.button( 1091 | "lnkSid", 1092 | w=290, 1093 | h=25, 1094 | l="LinkedIn(Siddarth)", 1095 | p=about_form, 1096 | en=1, 1097 | bgc=[0.2, 0.4, 0.76], 1098 | c="pm.launch(web='https://www.linkedin.com/in/siddarthmehraajm/')", 1099 | ) 1100 | 1101 | link_btnVish = pm.button( 1102 | "lnkVish", 1103 | w=290, 1104 | h=25, 1105 | l="LinkedIn(Vishal)", 1106 | p=about_form, 1107 | en=1, 1108 | bgc=[0.2, 0.4, 0.76], 1109 | c="pm.launch(web='https://www.linkedin.com/in/vishal-nagpal-82975a149/')", 1110 | ) 1111 | 1112 | how_to_btn = pm.button( 1113 | "how_to_btn", 1114 | w=290, 1115 | h=50, 1116 | l="How to Use This Tool (Youtube Demo)", 1117 | p=about_form, 1118 | en=1, 1119 | bgc=[0.6, 0.12, 0.12], 1120 | c="pm.launch(web='https://youtu.be/wTVYchvHAuU/')", 1121 | ) 1122 | 1123 | 1124 | pm.formLayout( 1125 | about_form, 1126 | e=1, 1127 | attachForm=[ 1128 | (about_txf, "top", 10), 1129 | (link_btnVish, "top", 97), 1130 | (link_btnSid, "top", 67), 1131 | (how_to_btn, "top", 130), 1132 | (about_txf, "left", 10), 1133 | (link_btnVish, "left", 10), 1134 | (link_btnSid, "left", 10), 1135 | (how_to_btn, "left", 10), 1136 | (about_txf, "right", 10), 1137 | (link_btnVish, "right", 10), 1138 | (link_btnSid, "right", 10), 1139 | (how_to_btn, "right", 10), 1140 | ], 1141 | ) 1142 | 1143 | 1144 | pm.showWindow(win_name) 1145 | 1146 | 1147 | # radio button change 1148 | def crv_skn_cc(): 1149 | pm.button(add_mesh_btn, e=1, en=1) 1150 | pm.button(add_df_btn, e=1, en=1) 1151 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 1152 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Skinned Curve") 1153 | pm.textField( 1154 | informatipn_txt_f, e=1, ed=0, nbg=1, pht="Add a Skinned Curve and Mesh" 1155 | ) 1156 | 1157 | 1158 | def softSel_skn_cc(): 1159 | pm.button(add_mesh_btn, e=1, en=0) 1160 | pm.button(add_df_btn, e=1, en=0) 1161 | pm.textField(mesh_textfield, e=1, en=0, pht=" ") 1162 | pm.textField(deformer_textfield, e=1, en=0, pht=" ") 1163 | pm.textField( 1164 | informatipn_txt_f, 1165 | e=1, 1166 | ed=0, 1167 | nbg=1, 1168 | pht="Select Verticies/Face with soft selection", 1169 | ) 1170 | 1171 | 1172 | def cl_skn_cc(): 1173 | pm.button(add_mesh_btn, e=1, en=1) 1174 | pm.button(add_df_btn, e=1, en=1) 1175 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 1176 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Cluster") 1177 | pm.textField(informatipn_txt_f, e=1, ed=0, nbg=1, pht="Add a Cluster and Mesh") 1178 | 1179 | 1180 | def df_skn_cc(): 1181 | pm.button(add_mesh_btn, e=1, en=1) 1182 | pm.button(add_df_btn, e=1, en=1) 1183 | pm.textField(mesh_textfield, e=1, en=1, pht="Add Mesh") 1184 | pm.textField(deformer_textfield, e=1, en=1, pht="Add Deformer") 1185 | pm.textField( 1186 | informatipn_txt_f, 1187 | e=1, 1188 | ed=0, 1189 | nbg=1, 1190 | pht="Add Wire/Wrap/Lattice/DeltaMush and a Mesh", 1191 | ) 1192 | 1193 | 1194 | def delta_to_skin_cc(): 1195 | pm.button(add_mesh_btn, e=1, en=1) 1196 | pm.button(add_df_btn, e=1, en=0) 1197 | pm.textField(mesh_textfield, e=1, en=1, pht=" ") 1198 | pm.textField(deformer_textfield, e=1, en=0, pht=" ") 1199 | pm.textField( 1200 | informatipn_txt_f, 1201 | e=1, 1202 | ed=0, 1203 | nbg=1, 1204 | pht="Add delta mush, delete delta after conversion", 1205 | ) 1206 | 1207 | 1208 | def blend_to_skin_cc(): 1209 | pm.button(add_mesh_btn, e=1, en=1) 1210 | pm.button(add_df_btn, e=1, en=0) 1211 | pm.textField(mesh_textfield, e=1, en=1, pht=" ") 1212 | pm.textField(deformer_textfield, e=1, en=0, pht=" ") 1213 | pm.textField( 1214 | informatipn_txt_f, 1215 | e=1, 1216 | ed=0, 1217 | nbg=1, 1218 | pht="Select mesh with BS, first bs will be converted", 1219 | ) 1220 | 1221 | 1222 | # convert functions 1223 | 1224 | 1225 | class con_to_skn: 1226 | def __init__(self): 1227 | self.msh = None 1228 | self.defr = None 1229 | 1230 | def add_mesh(self): 1231 | try: 1232 | Mymsh = str(pm.ls(sl=1)[0]) 1233 | if pm.objectType(pm.ls(pm.listHistory(Mymsh), typ="mesh")[0]) == "mesh": 1234 | pm.textField("mesh_field", e=1, tx=Mymsh) 1235 | self.msh = Mymsh 1236 | return self.msh 1237 | 1238 | except: 1239 | pm.error("Please select a Mesh") 1240 | 1241 | def add_deformer(self): 1242 | try: 1243 | Mydefr = str(pm.ls(sl=1)[0]) 1244 | option_functions = { 1245 | "crv_skn_rb": "curve", 1246 | "softsel_skn_rb": "soft", 1247 | "restdf_skn_rb": "rest", 1248 | "cls_skn_rb": "cluster", 1249 | "bs_skn_rb": "blend", 1250 | "smooth_skn_rb": "delta", 1251 | } 1252 | option = pm.radioCollection(radio_coll, q=1, sl=1) 1253 | 1254 | if option in option_functions: 1255 | if option_functions[option] == "curve": 1256 | if ( 1257 | pm.objectType( 1258 | pm.ls(pm.listHistory(Mydefr), typ="nurbsCurve")[0] 1259 | ) 1260 | == "nurbsCurve" 1261 | ): 1262 | pm.textField("df_field", e=1, tx=Mydefr) 1263 | print(Mydefr) 1264 | self.defr = Mydefr 1265 | return self.defr 1266 | elif option_functions[option] == "cluster": 1267 | if ( 1268 | pm.objectType( 1269 | pm.ls(pm.listHistory(Mydefr), typ="clusterHandle")[0] 1270 | ) 1271 | == "clusterHandle" 1272 | ): 1273 | pm.textField("df_field", e=1, tx=Mydefr) 1274 | print(Mydefr) 1275 | self.defr = Mydefr 1276 | return self.defr 1277 | 1278 | elif option_functions[option] == "soft": 1279 | pm.textField("df_field", e=1, tx=Mydefr) 1280 | self.defr = Mydefr 1281 | return self.defr 1282 | 1283 | elif option_functions[option] == "rest": 1284 | pm.textField("df_field", e=1, tx=Mydefr) 1285 | self.defr = Mydefr 1286 | return self.defr 1287 | elif option_functions[option] == "delta": 1288 | pm.textField("df_field", e=1, tx=Mydefr) 1289 | self.defr = Mydefr 1290 | return self.defr 1291 | elif option_functions[option] == "blend": 1292 | pm.textField("df_field", e=1, tx=Mydefr) 1293 | self.defr = Mydefr 1294 | return self.defr 1295 | 1296 | except: 1297 | pm.error("Please select the correct Deformer/Node") 1298 | 1299 | 1300 | 1301 | def main_convert_to_skin(self): 1302 | print(self.defr, self.msh) 1303 | dc = deformerConvert(deformer=self.defr, mesh=self.msh) 1304 | dc.deformer_skin_convert() 1305 | 1306 | def rest_deformer(self): 1307 | print(self.defr, self.msh) 1308 | dc = deformerConvert(deformer=self.defr, mesh=self.msh) 1309 | dc.rest_deformer_skin_convert() 1310 | 1311 | def SoftSelection(self): 1312 | dc = deformerConvert() 1313 | dc.SoftSelectionToConvert() 1314 | 1315 | def convert_cluster(self): 1316 | print(self.defr, self.msh) 1317 | dc = deformerConvert(deformer=self.defr, mesh=self.msh) 1318 | dc.ClusterConvert() 1319 | 1320 | def delta_skin(self): 1321 | print(self.defr, self.msh) 1322 | dc = deformerConvert(deformer=self.defr, mesh=self.msh) 1323 | dc.deltaMush_skin_convert() 1324 | 1325 | def blend_skin(self): 1326 | print(self.defr, self.msh) 1327 | dc = deformerConvert(deformer=self.defr, mesh=self.msh) 1328 | dc.blendShapeConvert() 1329 | 1330 | 1331 | # button functions 1332 | 1333 | 1334 | def jnt_btwn(): 1335 | t = JointProc() 1336 | t.CtrJnt(cmds.ls(sl=1)) 1337 | 1338 | 1339 | def jnt_each(): 1340 | t = JointProc() 1341 | t.CtrJntEach(cmds.ls(sl=1, fl=1)) 1342 | 1343 | 1344 | def tr_crv(): 1345 | t = JointProc() 1346 | t.transfroms_to_curve(pm.ls(sl=1)) 1347 | 1348 | 1349 | con = con_to_skn() 1350 | 1351 | 1352 | def mesh_add(): 1353 | c = con.add_mesh() 1354 | 1355 | 1356 | def deformer_add(): 1357 | c = con.add_deformer() 1358 | 1359 | 1360 | def convert_to_skin(): 1361 | pm.textField(time_elapsed_txf, e=1, ed=0, nbg=1, pht="Time Elapsed:") 1362 | start = time.time() 1363 | option_functions = { 1364 | "crv_skn_rb": con.main_convert_to_skin, 1365 | "softsel_skn_rb": con.SoftSelection, 1366 | "restdf_skn_rb": con.rest_deformer, 1367 | "cls_skn_rb": con.convert_cluster, 1368 | "smooth_skn_rb": con.delta_skin, 1369 | "bs_skn_rb": con.blend_skin, 1370 | } 1371 | option = pm.radioCollection(radio_coll, q=1, sl=1) 1372 | 1373 | if option in option_functions: 1374 | c = option_functions[option]() 1375 | else: 1376 | print("Option is wip") 1377 | end = time.time() 1378 | pm.textField( 1379 | time_elapsed_txf, 1380 | e=1, 1381 | ed=0, 1382 | nbg=1, 1383 | pht="Time Elapsed:%d seconds" % (end - start), 1384 | ) 1385 | print("Total time elapsed_%d" % (end - start)) 1386 | --------------------------------------------------------------------------------