def create(self): woHold = dict(self.wrapOptions) for wo in woHold: if (isinstance(self.wrapOptions[wo], basestring) and self.wrapOptions[wo] == "") or ( isinstance(self.wrapOptions[wo], bool) and self.wrapOptions[wo] == False ): del (self.wrapOptions[wo]) self.wrapOptions["type"] = "wrap" if len(self.deformed) > 0: self.deformed[0] = shape(self.deformed[0]) if len(iterable(mc.listHistory(self.deformed[0]))) == 0: duplicateShape(self.deformed[0], ah=True) self[:] = mc.deformer(self.deformed[0], **self.wrapOptions) if len(self.deformed) > 1: i = 1 for d in self.deformed[1:]: d = self.deformed[i] = shape(d) mc.deformer(self[0], e=True, g=d) new = mc.listConnections(self[0] + ".og[" + str(i) + "]", sh=True)[0] if d != new and mc.objExists(new): # new node has been created - rename mc.rename(d, d + "Orig#") mc.rename(new, d) i += 1 mc.setAttr(self[0] + ".maxDistance", self.maxDistance) if self.exclusiveBind: mc.setAttr(self[0] + ".exclusiveBind", True)
def duplicateShape(*args,**keywords): asHistory=False shortNames=\ { 'ah':'asHistory' } for k in keywords: if k in locals(): exec(k+'=keywords[k]') elif k in shortNames: exec(shortNames[k]+'=keywords[k]') if len(args)==0: args=mc.ls(sl=True) sel=[] for a in args: sel.extend(iterable(a)) for i in range(0,len(sel)): sel[i]=shape(sel[i]) returnVal=[] for sh in sel: tr=mc.listRelatives(sh,p=True)[0] trDup=mc.duplicate(tr,rc=True)[0] shDup=mc.listRelatives(trDup,s=True)[mc.listRelatives(tr,s=True).index(sh)] mc.parent(shDup,tr,s=True,add=True) mc.delete(trDup) returnVal.append(shDup) if asHistory: hist='' plugIn='' plugOut='' if mc.nodeType(sh)=='mesh': plugIn='.inMesh' plugOut='.outMesh' if mc.connectionInfo(sh+'.inMesh',id=True): hist=mc.connectionInfo(sh+'.inMesh',sfd=True) elif 'nurbs' in mc.nodeType(sh): plugIn='.create' plugOut='.local' if mc.connectionInfo(sh+'.create',id=True): hist=mc.connectionInfo(sh+'.create',sfd=True) if mc.objExists(sh+plugIn) and mc.objExists(shDup+plugIn): if mc.objExists(hist): mc.connectAttr(hist,shDup+plugIn,f=True) mc.connectAttr(shDup+plugOut,sh+plugIn,f=True) mc.setAttr(shDup+'.io',True) if len(returnVal)==1: return returnVal[0] elif len(returnVal)==0: return '' else: return returnVal
def __init__(self, *args, **keywords): # default options self.controlObjects = [""] self.baseShapes = [""] self.influences = [] self.deformed = [] self.nurbsSamples = [10.0] self.smoothness = [0.0] self.nurbsSamples = [10] self.wrapSmoothness = [1] self.exclusiveBind = True self.maxDistance = 0 self.calculateMaxDistance = False self.smooth = -1 self.smoothType = 0 self.wrapOptions = { "name": "", "before": False, "after": False, "split": False, "frontOfChain": False, "parallel": False, "prune": False, } self.shortNames = { "co": "controlObject", "bsa": "baseShapeAttr", "dsa": "deformShapeAttr", "d": "deformed", "n": "name", "bf": "before", "af": "after", "sp": "split", "foc": "frontOfChain", "par": "parallel", "pr": "prune", "eb": "exclusiveBind", "md": "maxDistance", "cmd": "calculateMaxDistance", } # attributes self.inputType = [] for k in keywords: if k in self.__dict__: exec("self." + k + "=keywords[k]") elif k in self.wrapOptions: exec('self.wrapOptions["' + k + '"]=keywords[k]') elif k in self.shortNames: if shortNames[k] in self.__dict__: exec("self." + shortNames[k] + "=keywords[k]") elif shortNames[k] in self.wrapOptions: exec('self.wrapOptions["' + shortNames[k] + '"]=keywords[k]') if isinstance(self.smoothType, basestring) and self.smoothType in ["exponential", "linear"]: self.smoothType = ["exponential", "linear"].index(self.smoothType) self.influences = iterable(self.influences) self.baseShapes = iterable(self.baseShapes) self.deformed = iterable(self.deformed) # parse arguments if len(args) == 0 and (len(self.influences) == 0 or len(self.deformed) == 0): args = mc.ls(sl=True) sel = [] for a in args: if ( isinstance(a, basestring) and len(a.split(".")) > 1 and str(mc.getAttr(a, type=True)) in ["mesh", "nurbsCurve", "nurbsSurface"] ) or ( isIterable(a) and len(mc.ls(a, o=True)) > 0 and mc.nodeType(mc.ls(a, o=True)[0]) in ["mesh", "nurbsCurve", "nurbsSurface"] ): sel.append(a) elif isinstance(a, basestring) and mc.nodeType(shape(a)) in ["mesh", "nurbsCurve", "nurbsSurface"]: sel.append(shape(a)) if len(self.influences) == 0 and len(self.deformed) == 0: self.influences = sel[:-1] self.deformed = sel[-1:] elif len(self.influences) == 0 and len(self.deformed) > 0: self.influences = sel elif len(self.influences) > 0 and len(self.deformed) == 0: self.deformed = sel self.create() self.addInfluences( nurbsSamples=self.nurbsSamples, wrapSmoothness=self.wrapSmoothness, controlObjects=self.controlObjects, smooth=self.smooth, smoothType=self.smoothType, *self.influences )
def addInfluences(self, *influences, **keywords): controlObjects = [""] baseShapes = [""] wrapSmoothness = [1] nurbsSamples = [10] smooth = -1 smoothType = 0 influences = list(influences) shortNames = {"co": "controlObjects"} for k in keywords: if k in locals(): exec(k + "=keywords[k]") elif k in shortNames: exec(shortNames[k] + "=keywords[k]") controlObjects = iterable(controlObjects) baseShapes = iterable(baseShapes) wrapSmoothness = iterable(wrapSmoothness) nurbsSamples = iterable(nurbsSamples) if self.influences == influences: self.influences = [] else: influencesHold = influences for inf in influencesHold: if inf in self.influences: influences.remove(inf) else: self.influences.append(inf) while len(controlObjects) < len(influences): controlObjects.append(controlObjects[-1]) while len(baseShapes) < len(influences): baseShapes.append(baseShapes[-1]) while len(wrapSmoothness) < len(influences): wrapSmoothness.append(wrapSmoothness[-1]) while len(nurbsSamples) < len(influences): nurbsSamples.append(nurbsSamples[-1]) for i in range(0, len(influences)): bsh = baseShapes[i] inf = influences[i] ctrlObj = controlObjects[i] nurbsSample = self.nurbsSamples[i] wrapSmooth = self.wrapSmoothness[i] infFaces = [] infSourceShape = "" infShape = "" infTr = "" shapeType = "" if isinstance(inf, basestring): if len(inf.split(".")) > 1: shapeType = str(mc.getAttr(inf, type=True)) if ( len(iterable(mc.ls(inf, o=True, type="dagNode"))) > 0 and len(iterable(mc.listRelatives(mc.ls(inf, o=True), p=True))) > 0 ): infTr = mc.listRelatives(mc.ls(inf, o=True), p=True)[0] infShape = shape(infTr) else: infShapeHist = iterable(mc.ls(iterable(mc.listHistory(inf, f=True, af=True)), type="shape")) if len(infShapeHist) > 0: infShape = infShapeHist[0] infTr = mc.listRelatives(infShape, p=True) else: shapeType = mc.nodeType(inf) infShape = infSourceShape = inf infTr = mc.listRelatives(inf, p=True) elif isIterable(inf): infShape = mc.ls(inf, o=True)[0] infTr = mc.listRelatives(infShape, p=True)[0] shapeType = mc.nodeType(infShape) if mc.nodeType(infShape) == "mesh": inf = mc.polyListComponentConversion(inf, tf=True) inputComponents = [] for fStr in inf: inputComponents.append(fStr.split(".")[-1]) pco = mc.createNode("polyChipOff") mc.setAttr(pco + ".dup", True) mc.setAttr(pco + ".inputComponents", len(inputComponents), type="componentList", *inputComponents) mc.connectAttr(infShape + ".outMesh", pco + ".ip") psep = mc.createNode("polySeparate") mc.setAttr(psep + ".ic", 2) mc.connectAttr(pco + ".out", psep + ".ip") inf = psep + ".out[1]" if not (isinstance(bsh, basestring) and mc.objExists(bsh)): bshSource = "" for m in removeAll(infShape, mc.ls(iterable(mc.listHistory(infShape)), type="mesh")): if ( len(mc.ls(m + ".vtx[*]", fl=True)) == len(mc.ls(infShape + ".vtx[*]", fl=True)) and len(mc.ls(m + ".f[*]", fl=True)) == len(mc.ls(infShape + ".f[*]", fl=True)) and len(mc.ls(m + ".e[*]", fl=True)) == len(mc.ls(infShape + ".e[*]", fl=True)) and len(removeAll(m, mc.listHistory(m))) == 0 ): isBSTarget = False for bsConn in iterable(mc.listConnections(m, type="blendShape", p=True)): if "inputTarget" in ".".join(bsConn.split(".")[1:]): isBSTarget = True break if isBSTarget: continue else: bshSource = m break if bshSource == "": bshSource = mc.createNode("mesh", p=infTr) mc.connectAttr(infShape + ".outMesh", bshSource + ".inMesh") mc.blendShape(infShape, bshSource, w=[1, 1]) mc.delete(bshSource, ch=True) mc.setAttr(bshSource + ".io", True) pco = mc.createNode("polyChipOff") mc.setAttr(pco + ".dup", True) mc.setAttr( pco + ".inputComponents", len(inputComponents), type="componentList", *inputComponents ) mc.connectAttr(bshSource + ".outMesh", pco + ".ip") psep = mc.createNode("polySeparate") mc.setAttr(psep + ".ic", 2) mc.connectAttr(pco + ".out", psep + ".ip") bsh = psep + ".out[1]" else: inf = infShape plug = firstOpenPlug(self[0] + ".basePoints") if isinstance(inf, basestring) and mc.objExists(inf): if len(inf.split(".")) <= 1: if mc.nodeType(shape(inf)) == "mesh": inf = shape(inf) + ".outMesh" else: inf = shape(inf) + ".local" if isinstance(bsh, basestring) and mc.objExists(bsh): if len(bsh.split(".")) <= 1: if mc.nodeType(shape(bsh)) == "mesh": bsh = shape(bsh) + ".outMesh" else: bsh = shape(bsh) + ".local" else: bshShape = mc.createNode(shapeType) if shapeType == "mesh": mc.connectAttr(inf, bshShape + ".inMesh") mc.blendShape(infShape, bshShape, w=(1, 1)) mc.delete(bshShape, ch=True) bsh = bsh + ".outMesh" else: mc.connectAttr(inf, bshShape + ".create") mc.blendShape(infShape, bshShape, w=(1, 1)) mc.delete(bshShape, ch=True) bsh = bsh + ".local" mc.setAttr(bshShape + ".io", True) # mc.connectAttr(inf,self[0]+'.driverPoints['+str(plug)+']',f=True) # mc.connectAttr(bsh,self[0]+'.basePoints['+str(plug)+']',f=True # poly smooth if shapeType == "mesh": pspInf = mc.createNode("polySmoothProxy") mc.setAttr(pspInf + ".kb", False) mc.connectAttr(inf, pspInf + ".ip") inf = pspInf + ".out" pspBase = mc.createNode("polySmoothProxy") mc.setAttr(pspBase + ".kb", False) mc.connectAttr(bsh, pspBase + ".ip") bsh = pspBase + ".out" mc.connectAttr(inf, self[0] + ".driverPoints[" + str(plug) + "]", f=True) mc.connectAttr(bsh, self[0] + ".basePoints[" + str(plug) + "]", f=True) # add wrap control attributes if not mc.objExists(ctrlObj): ctrlObj = infTr if shapeType == "mesh": if not "wrapSmoothLevels" in mc.listAttr(ctrlObj): mc.addAttr(ctrlObj, ln="wrapSmoothLevels", at="short", dv=0) mc.setAttr(ctrlObj + ".wrapSmoothLevels", k=False, cb=True) mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspInf + ".el") mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspBase + ".el") mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspInf + ".ll") mc.connectAttr(ctrlObj + ".wrapSmoothLevels", pspBase + ".ll") if not "wrapSmoothType" in mc.listAttr(ctrlObj): mc.addAttr( ctrlObj, ln="wrapSmoothType", at="enum", en="exponential:linear", min=0, max=1, dv=smoothType ) mc.setAttr(ctrlObj + ".wrapSmoothType", k=False, cb=True) mc.connectAttr(ctrlObj + ".wrapSmoothType", pspInf + ".mth") mc.connectAttr(ctrlObj + ".wrapSmoothType", pspBase + ".mth") if not "inflType" in mc.listAttr(ctrlObj): mc.addAttr(ctrlObj, ln="inflType", at="enum", en="none:point:face", min=1, max=2, dv=2) mc.setAttr(ctrlObj + ".inflType", k=False, cb=True) mc.connectAttr(ctrlObj + ".inflType", self[0] + ".inflType[" + str(plug) + "]") else: if not "nurbsSamples" in mc.listAttr(ctrlObj): mc.addAttr(ctrlObj, ln="nurbsSamples", at="short", dv=nurbsSample) mc.setAttr(ctrlObj + ".nurbsSamples", k=False, cb=True) mc.connectAttr(ctrlObj + ".nurbsSamples", self[0] + ".nurbsSamples[" + str(plug) + "]") if self.calculateMaxDistance: greatestDistance = 0.0 if shapeType == "mesh": distCheckMesh = mc.createNode("mesh", p=infTr) mc.connectAttr(inf, distCheckMesh + ".inMesh") deformedCP = "" if mc.nodeType(shape(self.deformed[0])) == "mesh": deformedCP = mc.createNode("closestPointOnMesh") mc.connectAttr(self.deformed[0] + ".worldMesh[0]", deformedCP + ".im") elif mc.nodeType(shape(self.deformed[0])) == "nurbsCurve": deformedCP = mc.createNode("closestPointOnCurve") mc.connectAttr(self.deformed[0] + ".worldSpace", deformedCP + ".ic") elif mc.nodeType(shape(self.deformed[0])) == "nurbsSurface": deformedCP = mc.createNode("closestPointOnSurface") mc.connectAttr(self.deformed[0] + ".worldSpace", deformedCP + ".is") for f in mc.ls(distCheckMesh + ".f[*]", fl=True): center = midPoint(f) mc.setAttr(deformedCP + ".ip", *center) closestPoint = mc.getAttr(deformedCP + ".p")[0] distance = distanceBetween(closestPoint, center) if distance > greatestDistance: greatestDistance = distance mc.disconnectAttr(inf, distCheckMesh + ".inMesh") mc.delete(distCheckMesh) if greatestDistance * 2 > mc.getAttr(self[0] + ".maxDistance"): mc.setAttr(self[0] + ".maxDistance", greatestDistance * 2) if shapeType == "mesh": if smooth >= 0: mc.setAttr(ctrlObj + ".wrapSmoothLevels", smooth) elif mc.nodeType(shape(self.deformed[0])) == "mesh": faceCount = 0 for d in self.deformed: if mc.nodeType(shape(d)) == "mesh": faceCount += len(mc.ls(shape(d) + ".f[*]", fl=True)) smoothSampleMesh = mc.createNode("mesh", p=infTr) mc.connectAttr(inf, smoothSampleMesh + ".inMesh") smoothFaceCount = 0 n = 0 while len(mc.ls(smoothSampleMesh + ".f[*]", fl=True)) < faceCount: mc.setAttr(ctrlObj + ".wrapSmoothLevels", n) n += 1 if len(mc.ls(smoothSampleMesh + ".f[*]", fl=True)) > faceCount * 1.5: mc.setAttr(ctrlObj + ".wrapSmoothLevels", mc.getAttr(ctrlObj + ".wrapSmoothLevels") - 1) mc.disconnectAttr(inf, smoothSampleMesh + ".inMesh") mc.delete(smoothSampleMesh)
def __init__(self,*args,**keywords): #default options self.targets=[] self.origin='local' self.frontOfChain=True self.deleteTargets=False self.base=[] self.baseIndex=0 self.useExisting=True self.controlObjects=[] self.controlAttributes=[] self.before=False self.after=False self.name='blendShape#' self.goals=[] # use to specify exact goal weights for each target in each target list self.range=[[0,10]] # use to specify range of goals for each target self.weights=[0] self.prune=False self.baseIndex=0 self.createControlObject=False self.control=True # any of the following abbreviations can be substituted self.shortNames=\ { 'o':'origin', 'foc':'frontOfChain', 'dt':'deleteTargets', 'b':'base', 'ue':'useExisting', 'co':'controlObjects', 'control':'controlObjects', 'ca':'controlAttributes', 'n':'name', 'g':'goals', 'goal':'goals', 'gm':'goalMax', 'p':'prune', 'r':'range', 't':'targets', 'w':'weights', 'c':'control' } unusedKeys={} for k in keywords: if k in self.shortNames: exec('self.'+self.shortNames[k]+'=keywords[k]') elif k in self.__dict__: exec('self.'+k+'=keywords[k]') else: unusedKeys[k]=keywords[k] self.controlObjects=iterable(self.controlObjects) if not isIterable(self.range[0]): self.range=[self.range] if len(args)==0: args=mc.ls(sl=True) sel=[] for a in args: if isinstance(a,basestring) and mc.objExists(a) and mc.nodeType(a)=='blendShape': self.append(a) self.base=mc.blendShape(a,q=True,g=True) for i in range(0,len(self.base)): self.base[i]=shape(self.base[i]) break else: sel.append(a) if len(self.base)>self.baseIndex and mc.objExists(self.base[self.baseIndex]): self.targets.extend(removeAll([self[0],self.base[self.baseIndex]],sel)) else: self.targets.extend(sel[:-1]) self.base=[shape(args[-1])] if self.useExisting and len(self[:])==0: self.find() if len(self)==0: self.create() self.addTargets(**self.__dict__)
def addTargets(self,*args,**keywords): targets=[] goals=[] goalRange=[[0,10]] deleteTargets=False base=self.base baseIndex=0 controlObjects=[] controlAttributes=[] prune=self.prune baseIndex=0 weights=[0] control=True shortNames=\ { 't':'targets', 'g':'goals', 'r':'goalRange', 'range':'goalRange', 'dt':'deleteTargets', 'b':'base', 'co':'controlObjects', 'ca':'controlAttributes', 'goal':'goals', 'p':'prune', 'w':'weights', 'c':'control' } for k in keywords: if k in shortNames: exec(shortNames[k]+'=keywords[k]') elif k in locals() and k!='shortNames': exec(k+'=keywords[k]') targets.extend(args) controlObjects=iterable(controlObjects) controlAttributes=iterable(controlAttributes) weights=iterable(weights) targetTrs=[] for i in range(0,len(targets)): targets[i]=iterable(targets[i]) targetTrs.append([]) for n in range(0,len(targets[i])): targets[i][n]=shape(targets[i][n]) targetTrs[-1].append(mc.listRelatives(targets[i][n],p=True)[0]) if len(targets)==0: raise Exception('BlendShape.addTargets() requires target(s).') return #double-check base index in case of changes to indexing geometry=iterable(mc.blendShape(self[0],q=True,g=True)) if shape(base[baseIndex]) in geometry: baseIndex=geometry.index(shape(base[baseIndex])) elif base[baseIndex] in geometry: baseIndex=geometry.index(base[baseIndex]) else: raise Exception('Shape '+shape(base[baseIndex])+' is not used by '+self[0]+'.') return while len(goals)<len(targets): goals.append([]) while len(weights)<len(targets): weights.append(weights[-1]) while len(goalRange)<len(targets): goalRange.append(goalRange[-1]) for i in range(0,len(targets)): t=iterable(targets[i]) g=iterable(goals[i]) r=iterable(goalRange[i]) if len(base)>1: matchingBases=[] tvs=len(mc.ls(t[-1]+'.vtx[*]',fl=True)) tfs=len(mc.ls(t[-1]+'.f[*]',fl=True)) tes=len(mc.ls(t[-1]+'.e[*]',fl=True)) for b in base: if\ ( tvs==len(mc.ls(b+'.vtx[*]',fl=True)) and tfs==len(mc.ls(b+'.f[*]',fl=True)) and tes==len(mc.ls(b+'.e[*]',fl=True)) ): matchingBases.append(b) if base[baseIndex] not in matchingBases and len(matchingBases)>0: baseIndex=base.index(matchingBases[-1]) index=firstOpenPlug(self[0]+'.it['+str(baseIndex)+'].itg') if len(g)>0 and g[-1]<g[0]: g.reverse() t.reverse() if len(g)>=len(t): r=[g[0],g[-1]] if len(r)==1 and isinstance(r[0],(float,long,int)): r=[r[0],r[0]+10] elif len(r)>2 and isinstance(r[0],(float,long,int)) and isinstance(r[-1],(float,long,int)): r=[r[0],r[-1]] elif len(r)==0 or not isinstance(r[0],(float,long,int)) or not isinstance(r[-1],(float,long,int)): r=[0,10] if r[-1]<r[0]: r.reverse() t.reverse() if t[-1] not in mc.blendShape(self[0],q=True,t=True): n=0 if len(g)==0: g.append(r[0]+(r[-1]-r[0])/len(t)) while len(g)<len(t): g.append(g[-1]+(r[-1]-g[-1])/(len(t)-len(g))) n+=1 for n in range(0,len(t)): mc.blendShape\ ( self[0], e=True, t=(base[baseIndex],index,t[n],g[n]), w=(index,weights[i]) ) goals[i]=g targets[i]=t goalRange[i]=r # if we don't have all the control attributes or we don't have a control object, make some up if len(controlObjects)==0 and len(targets)>0: controlObjects.append(mc.listRelatives(base[baseIndex],p=True)[0]) if len(controlObjects)>0: while len(controlObjects)<len(targets): controlObjects.append(controlObjects[-1]) n=0 while len(controlAttributes)<len(targetTrs): controlAttributes.append(targetTrs[n][-1].replace(base[baseIndex],'')) if controlAttributes[-1][0] in ['_','|']: controlAttributes[-1]=controlAttributes[-1][1:] controlAttributes[-1]=controlAttributes[-1][0].lower()+controlAttributes[-1][1:] n=+1 if control: for i in range(0,len(targets)): if mc.objExists(controlObjects[i]) and controlAttributes[i] not in removeDuplicates(mc.listAttr(controlObjects[i])): mc.addAttr\ ( controlObjects[i], ln=controlAttributes[i], at='double', dv=weights[i], k=True, smx=goalRange[i][-1], smn=goalRange[i][0] ) if not mc.isConnected(controlObjects[i]+'.'+controlAttributes[i],self[0]+'.'+targets[i][-1]): mc.connectAttr(controlObjects[i]+'.'+controlAttributes[i],self[0]+'.'+targets[i][-1],f=True) self.controlObjects.extend(controlObjects) self.targets.extend(targets) self.range.extend(goalRange) self.goals.extend(goals) self.base.extend(base) self.controlObjects.extend(controlObjects) self.controlAttributes.extend(controlAttributes)
def geoConnect(*args,**keywords): """ Connects shapes and worldSpace transforms of one shape to another, or all shapes in one file or namespace to another. Accepts an input of 2 or more file names, 2 or more name spaces, or any even number of objects. """ # default options driverNameSpace='' drivenNameSpace='' drivers=[] driven=[] hide=[] recursive=False maintainOffset=False output='' returnVal=[] shortNames=\ { 'r':'recursive', 'mo':'maintainOffset', 'o':'output', 'rv':'returnVal', 'h':'hide' } for k in keywords: if k in locals(): exec(k+'=keywords[k]') elif k in shortNames: exec(shortNames[k]+'=keywords[k]') if len(args)==0 and driverNameSpace=='' and drivenNameSpace=='': sel=iterable(mc.ls(sl=True)) sel=[] for a in args: sel.extend(iterable(a)) for i in range(0,len(sel)): if sel[i]=='': sel[i]=':' fromFiles=True for i in range(0,len(sel)): if len(sel[i].split('.'))>1: if not os.path.isfile(sel[i]): filePath=findFile(sel[i]) if os.path.isfile(filePath): sel[i]=filePath else: fromFiles=False break else: fromFiles=False break hide=iterable(hide) while len(hide)<len(sel): hide.append(False) matchByNameSpace=True if fromFiles: if len(sel)==1: sel.append(sel[0]) sel[0]=mc.file(q=True,l=True)[0] else: if mc.file(q=True,l=True)[0]!=sel[0]: mc.file(sel[0],o=True,f=True) driverNameSpace=mc.namespaceInfo(cur=True) drivenNameSpace=os.path.basename(sel[1].split('.')[0]) mc.file(sel[1],i=True,ra=True,namespace=drivenNameSpace,pr=True,loadReferenceDepth='all',options='v=1') else: nameSpaces=[':']+iterable(mc.namespaceInfo(lon=True)) for s in sel: if s not in nameSpaces: matchByNameSpace=False break if not matchByNameSpace: sel=iterable(mc.ls(sel)) matchNames=False if matchByNameSpace: currentNameSpace=mc.namespaceInfo(cur=True) if not fromFiles: if len(sel)>1: driverNameSpace=sel[0] if len(sel)==1: driverNameSpace=':' drivenNameSpace=sel[1] mc.namespace(set=driverNameSpace) for d in iterable(mc.ls(mc.namespaceInfo(ls=True),type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(d+'.io')==False: drivers.append(d) mc.namespace(set=drivenNameSpace) for d in iterable(mc.ls(mc.namespaceInfo(ls=True),type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(d+'.io')==False: driven.append(d) mc.namespace(set=currentNameSpace) drivers.sort() driven.sort() matchNames=True elif len(sel)>1: driven=sel[int(len(sel)/2):int(len(sel)/2)*2] drivers=sel[:int(len(sel)/2)] if recursive: matchNames=True drs=drivers dns=driven if len(drs)<=len(dns): r=len(drs) else: r=len(dns) for i in range(0,r): dr=drs[i] dn=dns[i] if shape(dr)!=dr or shape(dn)!=dn: drivers.remove(dr) driven.remove(dn) if shape(dr)!=dr and shape(dn)!=dn: drc=[] for dr in iterable(mc.listRelatives(dr,ad=True,type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(dr+'.io')==False: drc.append(dr) drc.sort() dnc=[] for dn in iterable(mc.listRelatives(dn,ad=True,type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(dn+'.io')==False: dnc.append(dn) dnc.sort() drivers.extend(drc) driven.extend(dnc) else: #check to see if we can match by name spaces if len(drivers[0].split(':'))>1 or len(driven[0].split(':'))>1: if len(drivers[0].split(':'))>1: driverNameSpace=':'.join(drivers[0].split(':')[:-1]) if len(driven[0].split(':'))>1: drivenNameSpace=':'.join(driven[0].split(':')[:-1]) matchNames=True if len(drivers)<=len(driven): r=len(drivers) else: r=len(driven) for i in range(0,r): if\ ( ( (driverNameSpace=='' and len(drivers[i].split(':'))<2) or ':'.join(drivers[i].split(':')[:-1])==driverNameSpace ) and ( (drivenNameSpace=='' and len(driven[i].split(':'))<2) or ':'.join(driven[i].split(':')[:-1])==drivenNameSpace ) and ( drivers[i].split(':')[-1]==driven[i].split(':')[-1] ) ): pass else: matchNames=False break driversHold=drivers drivenHold=driven drivers=[] driven=[] if len(drivers)<=len(driven): r=len(drivers) else: r=len(driven) for i in range(0,r): if shape(driversHold[i])!='' and shape(drivenHold[i])!='': drivers.append(shape(drivers[i])) drivers.append(shape(driven[i])) else: return if matchNames: # match names driverParents=[] driverHasSiblings=[] driversBN=[] for i in range(0,len(drivers)): driversBN.append(drivers[i].split('|')[-1].split(':')[-1]) driverParents.append(mc.listRelatives(drivers[i],p=True)[0].split('|')[-1].split(':')[-1]) sib=False for c in mc.listRelatives(driverParents[-1],c=True,type=mc.nodeType(drivers[i])): if c!=drivers[i] and mc.getAttr(c+'.io')==False: sib=True driverHasSiblings.append(sib) drivenParents=[] drivenParentLists=[] drivenBN=[] for i in range(0,len(driven)): #if driven[i].split(':')>1: drivenBN.append(driven[i].split('|')[-1].split(':')[-1]) drivenParentLists.append(iterable(mc.ls(driven[i],l=True)[0].split('|')[:-1])) for n in range(0,len(drivenParentLists[-1])): drivenParentLists[-1][n]=drivenParentLists[-1][n].split(':')[-1] drivenParents.extend(drivenParentLists[-1]) driversHold=drivers drivenHold=driven driven=[] drivers=[] for i in range(0,len(driversBN)): matched=False if (driverParents[i] in drivenParents) and not driverHasSiblings[i]: # match by transform names for n in range(0,len(drivenParentLists)): if driverParents[i] in drivenParentLists[n]: drivers.append(driversHold[i]) driven.append(drivenHold[n]) elif driversBN[i] in drivenBN: # match by shape names drivers.append(driversHold[i]) driven.append(drivenHold[drivenBN.index(driversBN[i])]) for i in range(0,len(drivers)): driverSh=drivers[i] drivenSh=driven[i] driverTr=mc.listRelatives(driverSh,p=True)[0] drivenTr=mc.listRelatives(drivenSh,p=True)[0] #drive shape if maintainOffset==False: shapeMatch=True else: shapeMatch=False if shapeMatch and mc.nodeType(driverSh)!=mc.nodeType(drivenSh): shapeMatch=False if shapeMatch and mc.nodeType(driverSh)=='nurbsCurve' or mc.nodeType(driverSh)=='nurbsSurface': if mc.ls(driverSh+'.cv[*]')!=mc.ls(drivenSh+'.cv[*]'): shapeMatch=False if shapeMatch and mc.nodeType(driverSh)=='mesh': if\ ( len(mc.ls(driverSh+'.vtx[*]',fl=True))!=len(mc.ls(drivenSh+'.vtx[*]',fl=True)) or len(mc.ls(driverSh+'.f[*]',fl=True))!=len(mc.ls(drivenSh+'.f[*]',fl=True)) or len(mc.ls(driverSh+'.e[*]',fl=True))!=len(mc.ls(drivenSh+'.e[*]',fl=True)) ): shapeMatch=False # try to connect with blendShape if shapeMatch: try: bs=BlendShape(driverSh,drivenSh,w=10,c=False)[0] returnVal.append(bs) except: shapeMatch=False # connect transforms mm=mc.createNode('multMatrix') dm=mc.createNode('decomposeMatrix') mc.connectAttr(driverTr+'.wm[0]',mm+'.i[1]') mc.connectAttr(drivenTr+'.pim',mm+'.i[0]') mc.connectAttr(mm+'.o',dm+'.imat') mc.connectAttr(dm+'.os',drivenTr+'.s') mc.connectAttr(dm+'.osh',drivenTr+'.sh') if shapeMatch: mc.parentConstraint(driverTr,drivenTr,mo=False) else: mc.parentConstraint(driverTr,drivenTr,mo=True) for attr in ['rp','rpt','sp','spt','ra','ro','it','rq']: for a in mc.listAttr(driverTr+'.'+attr): mc.connectAttr(driverTr+'.'+a,drivenTr+'.'+a,f=True) if not shapeMatch: # connect with wrap if mc.nodeType(driverSh)=='mesh' and mc.nodeType(drivenSh)=='mesh': driverArea=mc.polyEvaluate(driverSh,a=True) drivenArea=mc.polyEvaluate(drivenSh,a=True) areaPercDiff=(driverArea-drivenArea)/drivenArea if mc.nodeType(driverSh)=='mesh' and mc.nodeType(drivenSh)=='mesh' and areaPercDiff>.1: cpom=mc.createNode('closestPointOnMesh') mc.connectAttr(driverSh+'.worldMesh[0]',cpom+'.im') driverFaces=[] drivenFaces=iterable(mc.ls(drivenSh+'.f[*]',fl=True)) mc.progressWindow(st='Analyzing mesh...',title='Working',max=len(drivenFaces)/20,ii=True) n=0 for f in drivenFaces: mc.setAttr(cpom+'.ip',*midPoint(f)) driverFaces.append(driverSh+'.f['+str(mc.getAttr(cpom+'.f'))+']') if float(n)/20.0==int(n/20): mc.progressWindow(e=True,s=1) if mc.progressWindow(q=True,ic=True): if mc.objExists(cpom): mc.delete(cpom) mc.progressWindow(e=True,ep=True) raise Exception('User interupt.') n+=1 mc.progressWindow(e=True,ep=True) driverFaces=removeDuplicates(driverFaces) wrap=Wrap(driverFaces,drivenSh) if mc.objExists(cpom): mc.delete(cpom) else: wrap=Wrap(driverSh,drivenSh) returnVal.append(wrap) if hide[0]: mc.hide(driverSh) if hide[1]: mc.hide(drivenSh) if (fromFiles or matchByNameSpace) and len(sel)>2: return geoConnect(o=output,r=recursive,mo=maintainOffset,rv=returnVal,h=(hide[0]+hide[2:]),*(sel[0]+sel[2:])) elif output!='': # save if len(output.split('.'))<2: output=output+'.'+sel[0].split('.')[-1] if not os.path.isdir(os.path.dirname(output)): output=os.path.dirname(sel[0])+'/'+output if output.split('.')[-1]=='.ma': outputType='mayaAscii' else: outputType='mayaBinary' mc.file(rename=output) mc.file(f=True,save=True,type=outputType) else: return returnVal
def uniqueNames(*args,**keywords): """ With no keywords, returns a unique version of the given name(s). With re=True or raiseException=True : Ensures unique names are used in the scene and raises an error if there are duplicates present. With rn=True or rename=True : renames any object which have duplicate names. """ rename=False raiseException=False validate=False shortNames=\ { 'rn':'rename', 'v':'validate', 're':'raiseException' } for k in keywords: if k in locals(): exec(k+'=keywords[k]') elif k in shortNames: exec(shortNames[k]+'=keywords[k]') if len(args)==0: args=mc.ls(sl=True) if len(args)==0: args=mc.ls() sel=[] for a in args: sel.extend(iterable(a)) shapes=[] for s in sel: if mc.objExists(s) and shape(s)==s: shapes.append(s) sel=removeAll(shapes,sel)+shapes if validate: rename=False raiseException=False if rename: raiseException=False validate=False if raiseException: rename=False validate=False max=0 if rename or validate or raiseException: max=1 names=[] nonUnique=[] newNames={} baseNameRE=re.compile('(^[^0-9].*[^0-9])') for s in sel: sn=iterable(s.split('|'))[-1] ln=hierarchyOrder(removeDuplicates(mc.ls(sn,l=True)),r=True) if len(ln)>max: try: baseName=baseNameRE.match(sn).group(0) except: baseName=sn i=1 rn=s un=[] while mc.objExists(rn) or len(un)<len(ln): rn=baseName+str(i) if not mc.objExists(rn): un.append(rn) i+=1 names.append(un[0]) for i in range(0,len(ln)): if validate or rename: newNames[ln[i]]=un[i] if rename: mc.rename(ln[i],un[i]) else: nonUnique.append(ln[i]) else: names.append(s) if raiseException: if len(nonUnique)>0: print('##Non-unique names:##\n'+str(nonUnique)) raise Exception('Non-unique names found.') return nonUnique elif validate or rename: return newNames else: if len(sel)==1 and len(names)==1: return names[0] else: return names