def hierarchyBetween(*args,**keywords): sel=[] type='' if len(args)==0: sel=mc.ls(sl=True) for a in args: if isIterable(a): sel.extend(a) else: sel.append(a) for k in keywords: if k=='t' or k=='type': type=keywords[k] elif k in locals(): exec(k+'=keywords[k]') shortNames=mc.ls(sel,sn=True) longNames=mc.ls(sel,l=True) if shortNames[0] not in longNames[-1].split('|'): shortNames.reverse() longNames.reverse() hierarchy=longNames[-1].split('|') if shortNames[0] not in hierarchy: return [] hierarchyBetween=[] for i in range(hierarchy.index(shortNames[0]),len(hierarchy)): if type=='': h=mc.ls('|'.join(hierarchy[:i+1])) else: h=mc.ls('|'.join(hierarchy[:i+1]),type=type) if isIterable(h) and len(h)>0: hierarchyBetween.append(h[0]) return hierarchyBetween
def shape(*args,**keywords): all=False shortNames={ 'a':'all' } for k in keywords: if k in shortNames: exec(shortNames[k]+'=keywords[k]') if k in locals(): exec(k+'=keywords[k]') if len(args)==0: args=iterable(mc.ls(sl=True)) sel=[] for a in args: if isIterable(a) or mc.objExists(a): sel.append(mc.ls(a,o=True)) shapes=[] for s in sel: sh=iterable(mc.ls(s,s=True)) if len(sh)==0: sh=mc.listRelatives(s,c=True,s=True,ni=True) if len(iterable(sh))>0: if all: shapes.append(sh) else: shapes.append(sh[0]) if len(shapes)==1: return shapes[0] elif len(shapes)==0: return '' else: return shapes
def __init__(self, *args, **keywords): # default options self.world = "" self.parents = [] name = "" self.scale = True self.enumNames = [] self.enumNames = { "s": "scale", "w": "world", "p": "parents", "n": "name", "ps": "ParentSpace", "en": "enumNames", } # attributes self[:] = [] self.child = "" self.currentParent = "" self.parentConstraint = "" self.scaleConstraint = "" for k in keywords: if k in self.__dict__: exec("self." + k + "=keywords[k]") elif k in self.enumNames: exec("self." + enumNames[k] + "=keywords[k]") self.enumNames = iterable(self.enumNames) sel = [] if len(args) == 0: sel = mc.ls(sl=True) for a in args: if isIterable(a): for aa in a: if mc.objExists(a): sel.append(mc.ls(a))[0] elif mc.objExists(a): sel.append(mc.ls(a)[0]) if (len(sel) > 0 or self.child != "") and len(self) == 0: if self.child == "": self.child = sel[0] if mc.objExists(self.child + ".zenParentSpace") and mc.connectionInfo( self.child + ".zenParentSpace", id=True ): self.append(mc.listConnections(sel[0] + ".zenParentSpace", s=True, d=False)[0]) else: self.create(n=name) if len(sel) > 1: self.addParents(en=self.enumNames, *sel[1:]) self.setParent(sel[-1])
def distanceBetween(*args): # distance between two points if len(args) == 0: args = mc.ls(sl=True) if len(args) == 0: return p = [] for a in args: if isIterable(a) and len(a) >= 3 and isinstance(a[0], (float, long, int)) and len(a) >= 3: p.append(a) elif isinstance(a, basestring) and mc.objExists(a): if len(a.split(".")) > 1: try: p.append(mc.pointPosition(a)) except: pass else: try: p.append(mc.pointPosition(a + ".rp")) except: err = True if len(p) < 1: return if len(p) > 2: p[:] = p[:2] dx = abs(p[0][0] - p[1][0]) dy = abs(p[0][1] - p[1][1]) dz = abs(p[0][2] - p[1][2]) return sqrt(dx * dx + dy * dy + dz * dz)
def listNodeConnections(*args,**keywords): s=True d=True sn=False sel=[] if len(args)==0: sel=mc.ls(sl=True) for a in args: if isIterable(a): sel.extend(a) else: sel.append(a) for k in keywords: if k=='s' or k=='source': s=keywords[k] if k=='d' or k=='destination': d=keywords[k] if k=='sn' or k=='shortName': sn=keywords[k] elif k in locals(): exec(k+'=keywords[k]') connections=[] for conn in removeDuplicates(mc.listConnections(sel[0],s=s,d=d,p=True)): if len(sel)==1 or mc.ls(conn,o=True)[0]==sel[1]: if mc.connectionInfo(conn,isSource=True): for dfs in mc.connectionInfo(conn,dfs=True): if mc.ls(dfs,o=True)[0]==sel[0]: if sn: connections.append\ ( [ mc.ls(conn,o=True)[0]+'.'+mc.listAttr(conn,sn=True)[0], mc.ls(dfs,o=True)[0]+'.'+mc.listAttr(dfs,sn=True)[0] ] ) else: connections.append([conn,dfs]) if mc.connectionInfo(conn,id=True): sfd=mc.connectionInfo(conn,sfd=True) if mc.ls(sfd,o=True)[0]==sel[0]: if sn: connections.append\ ( [ mc.ls(sfd,o=True)[0]+'.'+mc.listAttr(sfd,sn=True)[0], mc.ls(conn,o=True)[0]+'.'+mc.listAttr(conn,sn=True)[0] ] ) else: connections.append([sfd,conn]) return removeDuplicates(connections)
def removeAll(removeList, origList): if not isIterable(origList): if isinstance(origList,(basestring,float,int,long)): origList=[origList] else: return [] if not isIterable(removeList): if isinstance(removeList,(basestring,float,int,long)): removeList=[removeList] else: return [] returnVal=[] if isIterable(removeList): for o in origList: if o not in removeList: returnVal.append(o) return returnVal
def addAutoFlex(self,mirror=True,pose={},**keywords): "Adds an auto-flex pose from the current pose or a dictionary of attribute/value pairs." self.bindPose= mc.dagPose(self.Muscle,q=True,bp=True)[0] self.root=mc.dagPose(self.bindPose, q=True, m=True )[0] startPose=mc.dagPose(self.root,s=True)#store current pose plug=mel.eval('zenFirstOpenPlug("'+self.Handle+'.zenAutoFlex")') verified=False attributes={} poses=[] success=True offBindPoseJointCount=0 dp=mc.dagPose(self.bindPose,q=True,ap=True) if isIterable(dp): offBindPoseJointCount=len(dp) if(offBindPoseJointCount>0 and len(pose)==0): #create an auto-flex pose from the current position command='rigZenMuscleAddAutoFlex("'+self.Handle+'",'+str(int(mirror))+')' plug=mel.eval(command) elif(len(pose)>0): success=self.goToPose(**pose) if(success): try: plug=mel.eval('rigZenMuscleAddAutoFlex("'+self.Handle+'",'+str(int(mirror)*self.getAxis())+')') except: success=False#raise Warning('Could not add auto flex pose for '+self.Muscle) if success: for k in keywords: attr='zenAutoFlex['+str(plug)+'].'+str(k) conn=mc.listConnections((self.Handle+'.'+attr),s=True,d=False,p=True) if isIterable(conn) and len(conn)>0 and mc.ls(conn[0],o=True)[0]==mc.ls((self.Handle+'.'+attr),o=True)[0]: attr=conn[0].split('.')[-1] attributes[str(attr)]=keywords[k] self.setAttributes(**attributes) success=self.goToPose(startPose) else: self.goToPose(startPose) mc.delete(startPose) return success
def iterable(arg): if type(arg).__name__=='NoneType': return [] if not isIterable(arg): if isinstance(arg,(basestring,float,int,long)): return [arg] else: return [] else: return arg
def getInfluences(self): #get influence objects self.influences=list() self.allCurves=list() if(not mc.objExists(self.Handle+'.zmi[0].zmim')): return for i in range(0,len(mc.ls(self.Handle+'.zmi[*]'))): self.influences.append(dict()) self.influences[i]['mesh']=str(mc.listConnections(self.Handle+'.zmi['+str(i)+'].zmim',sh=True)[0]) self.influences[i]['curves']=list() self.influences[i]['edges']=list() self.influences[i]['parents']=list() for c in mc.ls(self.Handle+'.zmi['+str(i)+'].zmics[*]'): if( isinstance(mc.listConnections(c+'.zmic'),list) and len(mc.listConnections(c+'.zmic'))>0): curve=mc.listConnections(c+'.zmic')[0] self.influences[i]['curves'].append(curve) self.allCurves.append(curve) edgeList=[] index=c.split('[')[(len(c.split('['))-1)].split(']')[0] edgeIndices=mc.getAttr(c+'.zmie')[0] if( len(self.influences[i]['mesh'])>0 ): for e in edgeIndices: edgeList.append(self.influences[i]['mesh']+'.e['+str(int(e))+']') self.influences[i]['edges'].append(edgeList) parentDictionary={} pc=mc.parentConstraint(curve,q=True) if(isinstance(pc,basestring)): parents=mc.parentConstraint(pc,q=True,tl=True) parentWeights=mc.parentConstraint(parents,pc,w=True,q=True) if not isIterable(parents): parents=[parents] if not isIterable(parentWeights): parentWeights=[parentWeights] for ppc in range(0,len(parents)): pcName=parents[ppc] pcWeight=parentWeights[ppc] if isinstance(pcName,basestring) and len(pcName) and isinstance(pcWeight,(float,int,long)): parentDictionary[pcName]=pcWeight else: parents=mc.listRelatives(curve,p=True) if(isinstance(parents,list) and len(parents)>0): parentDictionary[parents[0]]=1 self.influences[i]['parents'].append(parentDictionary)
def generateScript(): sel=mc.ls("*.zenMuscleInputs",o=True,sl=True) if not isIterable(sel) or len(sel)==0: sel=mc.ls("*.zenMuscleInputs",o=True) if not isIterable(sel): raise('You must select one or more muscles or Muscle Handle from which to generate creation scripts.') returnVal='' completed=[] for m in sel: myMuscle=Muscle(m) if myMuscle.Muscle not in completed: returnVal+=myMuscle.generateScript() completed.append(myMuscle.Muscle) if('opposite' in myMuscle.__dict__): completed.append(myMuscle.opposite.Muscle) if len(returnVal)>0: returnVal='import maya.mel as mel\nmel.eval("source zenTools")\nimport zen\n'+returnVal mel.eval('zenDisplayText("Muscle Script","'+mc.encodeString(returnVal)+'")') return returnVal
def removeDuplicates(iterable): if not isIterable(iterable): if isinstance(iterable,(basestring,float,int,long)): return [iterable] else: return [] returnVal=[] for item in iterable: if item not in returnVal: returnVal.append(item) return returnVal
def melEncode(arg): if isinstance(arg,basestring): return '"'+mc.encodeString(arg)+'"' elif isIterable(arg): returnVal='{' for i in range(0,len(arg)): if(isIterable(arg[i])): returnVal+='"' for n in range(0,len(arg[i])): returnVal+=str(arg[i][n]) if n<len(arg[i])-1 and len(str(arg[i][n]))>0: returnVal+=',' returnVal+='"' else: returnVal+=melEncode(arg[i]) if i<len(arg)-1 and len(str(arg[i]))>0: returnVal+=',' returnVal+='}' return returnVal return unicode(arg)
def set(self,val): if self.type=='vector':#vectors must be explicitly set if isIterable(val): if isIterable(val[0]): self.array=True valString='{' for i in range(0,len(val)): valString+='<<'+unicode(val[i][0])+','+unicode(val[i][1])+','+unicode(val[i][2])+'>>' if i<(len(val)-1): valString+=',' else: valString+='}' else: valString='<<'+unicode(val[0])+','+unicode(val[1])+','+unicode(val[2])+'>>' else: if isIterable(val): self.array=True if len(val)>0: testVal=val[0] else: testVal='' else: testVal=val if isinstance(testVal,basestring): self.type='string' if isinstance(testVal,(int,long,float)): if self.type!='' and self.type in ['int','float']: pass else: if isinstance(testVal,float): self.type='float' else: self.type='int' valString=melEncode(val) cmd=self.type+' '+self.name if self.array: cmd+='[]' cmd+='='+valString return mel.eval(cmd)
def goToDagPose(*args,**keywords): bindPose=False shortNames={'bp':'bindPose'} for k in keywords: if k in locals(): exec(k+'=keywords[k]') if k in shortNames: exec(shortNames[k]+'=keywords[k]') sel=[] if len(args)==0: sel=mc.ls(sl=True) for a in args: if isIterable(a): sel.extend(a) else: sel.append(a) if len(iterable(mc.ls(sel,type='dagPose')))==0 or bindPose: sel=removeDuplicates(mc.dagPose(mc.listConnections(mc.ls(mc.listHistory(sel)),type='transform'),q=True,bp=True)) if len(sel)==0: return mel.eval('DisableAll') success=True err=True for i in range(0,10): try: mc.dagPose(sel[0],r=True) err=False break except: err=True mel.eval('EnableAll') if err and len(iterable(mc.dagPose(q=True,ap=True))): success=False if success: return sel[0] else: return
def sortBy(*args,**keywords): sorted=[] sel=[] if len(args)==1: if isIterable(args[0]) and len(args[0])>1: sorted=list(args[0][-1]) sel=list(args[0][0]) inputType=type(args[0][0]).__name__ else: return elif len(args)>1: sorted=list(args[-1]) sel=list(args[0]) inputType=type(args[0]).__name__ l=sorted[:] for s in l: if s not in sel: sorted.remove(s) unsorted=sel[0:0] for s in sel: if s not in sorted: unsorted=unsorted+[s] if inputType=='str' or inputType=='unicode': unsorted=''.join(unsorted) sorted=''.join(sorted) elif inputType=='dict': sorted=list(sorted) unsorted=list(unsorted) else: exec('sorted='+inputType+'(sorted)') exec('unsorted='+inputType+'(unsorted)') return(sorted+unsorted)
def sortBy(*args, **keywords): sorted = [] sel = [] if len(args) == 1: if isIterable(args[0]) and len(args[0]) > 1: sorted = list(args[0][-1]) sel = list(args[0][0]) inputType = type(args[0][0]).__name__ else: return elif len(args) > 1: sorted = list(args[-1]) sel = list(args[0]) inputType = type(args[0]).__name__ l = sorted[:] for s in l: if s not in sel: sorted.remove(s) unsorted = sel[0:0] for s in sel: if s not in sorted: unsorted = unsorted + [s] if inputType == 'str' or inputType == 'unicode': unsorted = ''.join(unsorted) sorted = ''.join(sorted) elif inputType == 'dict': sorted = list(sorted) unsorted = list(unsorted) else: exec('sorted=' + inputType + '(sorted)') exec('unsorted=' + inputType + '(unsorted)') return (sorted + unsorted)
def normalize(*args):#normalize a vector aa=[] v=[] for a in args: if isIterable(a): aa.extend(a) else: aa.append(a) for a in aa: if isinstance(a,(float,int,long)): v.append(float(a)) if len(v)<3: raise Exception('normalize requires an input of 3 numbers') if len(v)>3: v[:]=v[:3] factor=1.0 vLen=v[0]*v[0]+v[1]*v[1]+v[2]*v[2]; if vLen==0: return factor=1.0/sqrt(vLen) if factor!=1.0: v[0]*=factor v[1]*=factor v[2]*=factor return v
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 generateScript(self): returnVal=self.Muscle+'=zen.Muscle\\\n' returnVal+='(\n' connections=mc.listConnections(self.Handle+'.zmi',type='transform') if isIterable(connections) and len(connections)>0:#if this is a mirrored Handle use the original if(len(connections)==1): if(mc.objExists(connections[0]+'.zmi')): opposite=Muscle(Handle=connections[0]) return(opposite.generateScript()) self.getInfluences() selectionGroups=[] parentConstraintWeights=[] n=0 for i in range(0,len(self.influences)):#get the span components selectionGroups.append([]) #parentConstraintWeights.append({}) mesh=str(self.influences[i]['mesh']) curves=self.influences[i]['curves'] edges=self.influences[i]['edges'] parents=self.influences[i]['parents'] if(len(parents)): for p in parents: for pc in p: if pc not in selectionGroups[i]: selectionGroups[i].append(pc) #parentConstraintWeights[i][pc]=p[pc] parentConstraintWeights.append(p) if(len(edges)): for e in edges: for ee in e: selectionGroups[i].append(ee) else: for c in curves: selectionGroups[i].append(c) for i in range(0,len(selectionGroups)):#span selection groups returnVal+=' [' for n in range(0,len(selectionGroups[i])): returnVal+='"'+selectionGroups[i][n]+'"' if(n==len(selectionGroups[i])-1): returnVal+='],\n' else: returnVal+=',' #set the parent constraint weights returnVal+=' pcw=[' dStrings=[] for i in range(0,len(parentConstraintWeights)): returnVal+='{' diStrings=[] for x in parentConstraintWeights[i]: diStrings.append('"'+x+'":'+str(parentConstraintWeights[i][x])) returnVal+=','.join(diStrings) if(i<len(parentConstraintWeights)-1): returnVal+='},' else: returnVal+='}]' attrList=[] delList=[] attrList.extend(mc.listAttr(self.Handle,k=True)) attrList.extend(mc.listAttr(self.Handle,cb=True)) for i in range(0,len(attrList)): if mc.objExists(self.Handle+'.'+attrList[i]) and mc.getAttr(self.Handle+'.'+attrList[i],type=True)!='message': c=mc.listConnections(self.Handle+'.'+attrList[i],s=True,d=False) if isIterable(c) and len(c)>0: delList.append(attrList[i]) else: delList.append(attrList[i]) delList.extend(['visibility','translateX','translateY','translateZ','rotateX','rotateY','rotateZ','scaleX','scaleY','scaleZ']) for d in delList: attrList.remove(d) tempList=attrList attrList=[] for a in tempList: if(len(a.split('.'))==1 and mc.getAttr(self.Handle+'.'+a,type=True)!='message'): attrList.append(a) if(len(attrList)>0): returnVal+=',\n ' for i in range(0,len(attrList)): returnVal+=attrList[i]+'='+str(mc.getAttr(self.Handle+'.'+attrList[i])) if(i<len(attrList)-1): returnVal+=',' returnVal+=',\n' #get the name if "opposite" in self.__dict__: returnVal+=' name=["'+self.Muscle+'","'+self.opposite.Muscle+'"],\n' else: returnVal+=' name="'+self.Muscle+'",\n' returnVal+=' axis='+str(self.getAxis())+',' returnVal+='spans='+str(self.spans)+',' if(mc.objExists(self.Handle+'.jiggle')): returnVal+='jiggle=True\n' else: returnVal+='jiggle=False\n' returnVal+=')\n' #auto-flex autoFlexPlugs=mc.ls(self.Handle+'.zaf[*]') if(isinstance(autoFlexPlugs,list) and len(autoFlexPlugs)>0): for p in autoFlexPlugs: infAttrs=mc.listConnections(p+'.zenPoseAttr',p=True,s=True,d=False) infAttrValues=[] if isIterable(infAttrs): for i in range(0,len(infAttrs)): attributeValue=mc.getAttr(p+'.zenAttrVal['+str(i)+']') if(isinstance(attributeValue,(float,int,long))): infAttrValues.append(attributeValue) elif(isIterable(attributeValue)): infAttrValues.append(attributeValue[0]) counter=0 if(isinstance(infAttrs,list) and isinstance(infAttrValues,list)): length=len(infAttrs) if(len(infAttrValues)<length): length=len(infAttrValues) if(length>0): if(counter==0): returnVal+=self.Muscle+'.addAutoFlex\\\n(\n' if "opposite" in self.__dict__: returnVal+=' mirror=True,\n' returnVal+=' pose={' for i in range(0,length): returnVal+='"'+infAttrs[i]+'":'+str(infAttrValues[i]) if(i<length-1): returnVal+=',' else: returnVal+='},\n ' attrList=mc.listAttr(p,leaf=True) if(isinstance(attrList,list) and len(attrList)>0): ii=0 for i in range(0,len(attrList)): if mc.objExists(p+'.'+attrList[i]): c=mc.listConnections(p+'.'+attrList[i],s=True,d=False) if\ ( mc.getAttr(p+'.'+attrList[i],type=True)=='double' and ( not(isIterable(c)) or len(c)==0 or mc.ls(c,o=True)[0]==mc.ls(p,o=True)[0] ) ): if(ii>0): returnVal+=',' returnVal+=attrList[i]+'='+str(mc.getAttr(p+'.'+attrList[i])) ii+=1 counter+=1 if(counter>0): returnVal+='\n)\n' return returnVal
def __init__(self,*args,**keywords): #check to make sure unique names are used in scene uniqueNames(iterable(mc.ls(type='dagNode')),re=True) # default options self.createSurface=False # use for IK's etc. - creates a surface instead of a curve self.scaleLength=True # use for IK's etc. - compensates for scale self.stretch=-1 # maximum stretch %: 0 > Infinity self.squash=-1 # maximum squash %: 0 > 100 self.arcWeight=.5 # controls the balance of rotational control weight alloted to the end Handle vs the base Handle self.width=1 # surface width self.length=10 # only used if no arguments are passed self.parents=['',''] # create under parent or parents self.softParents=['',''] self.parentSpaces=['',''] self.names=['ArcCtrl#','arcCtrl_handle#'] # self.handleType=['locator','locator'] # see 'Handle' class - 'locator','doubleEllipse', self.handleOptions=[{},{}] # dictionaries passed on to the Handle class for options concerning placement of handles self.aim=(0,1,0) self.poleVector=(0,0,1) # if only two arc points are given, it will try to point the arc in this direction if possible # option abbreviations shortNames=\ { 'p':'parents', 'cs':'createSurface', 'pv':'poleVector', 'st':'stretch', 'sq':'squash', 'cs':'createSurface', 'n':'names', 'ho':'handleOptions', 'w':'width', 'pv':'poleVector', 'aw':'arcWeight', 'ht':'handleType', 'sp':'softParents' } if 'shortNames' in self.__dict__: # this is done so that we don't wipe out added short names in inheriting classes for sn in shortNames: self.shortNames[sn]=shortNames[sn] else: self.shortNames=shortNames for k in keywords: #get user options if k in self.shortNames: exec('self.'+self.shortNames[k]+'=keywords[k]') elif k in self.__dict__: exec('self.'+k+'=keywords[k]') #check and format options if\ ( len(iterable(self.aim))<3 or not isinstance(self.aim[0],(float,int,long)) or not isinstance(self.aim[1],(float,int,long)) or not isinstance(self.aim[2],(float,int,long)) ): self.aim=(0,1,0) if\ ( len(iterable(self.poleVector))<3 or not isinstance(self.poleVector[0],(float,int,long)) or not isinstance(self.poleVector[1],(float,int,long)) or not isinstance(self.poleVector[2],(float,int,long)) ): self.poleVector=(0,0,1) self.aim=normalize(self.aim) self.poleVector=normalize(self.poleVector) if len(iterable(self.softParents))==1: self.softParents=[iterable(self.softParents)[0],iterable(self.softParents)[0]] elif len(iterable(self.softParents))==0: self.softParents=['',''] if len(iterable(self.parents))==1: self.parents=[iterable(self.parents)[0],iterable(self.parents)[0]] elif len(iterable(self.parents))==0: self.parents=['','.'] if len(iterable(self.names))==1: self.names=[iterable(self.names)[0],iterable(self.names)[0]] if len(iterable(self.names))==0: self.names=['',''] if len(iterable(self.handleType))==1: self.handleType=[iterable(self.handleType)[0],iterable(self.handleType)[0]] if len(iterable(self.handleType))==0: self.handleType=['',''] if isinstance(self.handleOptions,dict): self.handleOptions=[self.handleOptions,self.handleOptions] if isinstance(self.handleOptions,(list,tuple)) and\ len(self.handleOptions)==1 and\ isinstance(self.handleOptions[0],dict): self.handleOptions=[self.handleOptions[0],self.handleOptions[0]] if self.stretch>=0 and self.squash<0 or self.stretch<0 and self.squash>=0:# squash & stretch come as a pair, set one to 0 if only 1 is set if self.stretch<0: self.stretch=0 if self.squash<0: self.squash=0 if not isinstance(self.poleVector,tuple): self.poleVector=tuple(self.poleVector) # attributes self.outputCurve='' self.outputNormal='' self.surface='' self.outputSurface='' self.handleShapes=[] self.curveShapes=[] self.arcPoints=[] self.handles=[] # parse arguments if len(args)==0: args=iterable(mc.ls(sl=True,fl=True)) # if no arguments are input, use selection if len(args)==0: args=[[0.0,0.0,0.0]] sel=[] for a in args: if isIterable(a) and not isinstance(a[0],(float,long,int)): sel.extend(a) else: sel.append(a) for s in sel: if isIterable(s) and isinstance(s[0],(float,long,int)) and len(s)>=3: self.arcPoints.append(s) elif isinstance(s,basestring) and mc.objExists(s): err=True if len(s.split('.'))>1: try: self.arcPoints.append(mc.pointPosition(s)) err=False except: err=True else: try: self.arcPoints.append(mc.pointPosition(s+'.rp')) err=False except: err=True if len(self.arcPoints)<2: if len(self.arcPoints)==0: self.arcPoints=[[0.0,0.0,0.0]] self.arcPoints=\ [ self.arcPoints[0], [ float(self.arcPoints[0][0])+float(self.aim[0])*self.length, float(self.arcPoints[0][1])+float(self.aim[1])*self.length, float(self.arcPoints[0][2])+float(self.aim[2])*self.length ] ] self.create()
def __init__(self,*args,**keywords): #set defaults name='' self.spanGroups={} attributes={} self.axis=0 self.jiggle=0 self.script=0 self.cMuscleShape='' self.Muscle='' self.muscleShape='' self.Handle='' self.allCurves=[] self.selectionGroups=[] pcw={} self.resMult=1.5 self.spans=12 for k in keywords: if(isinstance(keywords[k],list) and (k=='pcw' or k=='parentConstraintWeights')):#interpret parent constraint weights pcw=keywords[k] if(isinstance(keywords[k],bool)):#convert booleans to integers exec('self.'+k+'='+str(int(keywords[k]))) elif(k=='axis'):#convert axis input to integer if(isinstance(keywords[k],str)): if(keywords[k].lower()=='x'): self.axis=1 if(keywords[k].lower()=='y'): self.axis=2 if(keywords[k].lower()=='z'): self.axis=3 elif(isinstance(keywords[k],int)): self.axis=keywords[k] elif(k=='name'): name=keywords[k] elif(k in self.__dict__): exec('self.'+k+'=keywords[k]') else: attributes[k]=keywords[k] if len(args)==0 and len(self.Handle)==0 and len(self.Muscle)==0 and len(self.muscleShape)==0: args=mc.ls(sl=True) for arg in args: if(isinstance(arg,list)): aList=arg else: aList=[arg] sList=aList for a in aList: if(mc.objExists(a) and mc.ls(a,o=True)[0]==mc.ls(a)[0]): if(mc.objExists(a+'.zmi')): self.Handle=a sList.remove(a) else: if(mc.nodeType(a)=='nurbsSurface'): aShape=a else: try: aShape=mc.listRelatives(c=True,s=True,ni=True,type='nurbsSurface')[0] except: aShape='' if(mc.objExists(aShape)): messageConnections=mc.listConnections(aShape+'.message',p=True,d=True,s=False) if(isinstance(messageConnections,list) and len(messageConnections)>0): for c in mc.listConnections(a+'.message',p=True,d=True): if(c.split('.')[1]=='zenMuscle'): self.Handle=c.split('.')[0] sList.remove(a) if isIterable(sList) and len(sList)>0: self.selectionGroups.append(sList) if(len(self.Muscle)>0 and len(self.muscleShape)==0): try: self.muscleShape=mc.listRelatives(self.Muscle,s=True,ni=True,type='nurbsSurface')[0] except: pass if(len(self.muscleShape)>0 and len(self.Handle)==0): for c in listConnections(self.muscleShape+'.message',p=True,d=True,s=False): if(c.split('.')[1]=='zenMuscle'): self.Handle=c.split('.')[0] break if(len(self.Handle)>0 and len(self.Muscle)==0 and mc.objExists(self.Handle+'.zenMuscle')): #if we know the Handle already, get the Muscle try: self.Muscle=mc.listConnections(self.Handle+'.zenMuscle')[0] except: pass if(len(self.Handle)>0 and len(self.muscleShape)==0 and mc.objExists(self.Handle+'.zenMuscle')):#get the Muscle shape try: self.muscleShape=mc.listConnections(self.Handle+'.zenMuscle',sh=True)[0] except: pass try: self.handleGroup=mc.listConnections(self.Handle+'.zenMuscleCtrlGroup')[0] except: pass if(len(self.Handle)>0 and self.axis>=0):#see if there is an opposite if(isinstance(mc.listConnections(self.Handle+'.zenOpposite'),list)): opp=mc.listConnections(self.Handle+'.zenOpposite')[0] if(mc.objExists(opp)): self.opposite=Muscle(Handle=opp,axis=-1) if len(self.muscleShape): self.spans=mc.getAttr(self.muscleShape+'.spansU') if( len(self.selectionGroups)>0 ): if(len(self.Muscle)==0 and len(self.Handle)==0): self.create() self.getInfluences() if( len(self.selectionGroups)>0 ): if(len(name)>0): if(isinstance(name,str)): self.rename(name) elif(isinstance(name,list)): self.rename(name[0]) if "opposite" in self.__dict__: self.opposite.rename(name[1]) self.setAttributes(**attributes) self.setParentConstraintWeights(*pcw)
def create(self): worldMatrixNode=mc.createNode('fourByFourMatrix') wm=\ [ [1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1] ] for a in range(0,4): for b in range(0,4): mc.setAttr( worldMatrixNode+'.in'+str(a)+str(b), wm[a][b] ) self.worldMatrix=worldMatrixNode+'.o' wsMatrices=[] cleanup=[] lattices=[] uvPos=[] antipodes=[] cpos=mc.createNode('closestPointOnSurface') if 'surfaceAttr' not in self.__dict__ or len(self.surfaceAttr)==0 and len(self.edges)>0: mc.select(self.edges) rebuildNode,surfaceNodeTr=mel.eval('zenLoftBetweenEdgeLoopPathRings(2)')[:2] self.surfaceAttr=rebuildNode+'.outputSurface' children=mc.listRelatives(surfaceNodeTr,c=True,s=True,ni=True,type='nurbsSurface') if isIterable(children) and len(children)>0: self.uSpans=mc.getAttr(children[0]+'.spansU') self.vSpans=mc.getAttr(children[0]+'.spansV') mc.disconnectAttr(self.surfaceAttr,surfaceNodeTr+'.create') mc.delete(surfaceNodeTr) if self.uSpans<0 or self.vSpans<0: tempTr=mc.createNode('transform') tempCurve=mc.createNode('nurbsCurve',p=tempTr) mc.connectAttr(self.surfaceAttr,tempCurve+'.create') self.uSpans=mc.getAttr(tempCurve+'.spansU') self.vSpans=mc.getAttr(tempCurve+'.spansV') mc.disconnectAttr(self.surfaceAttr,tempCurve+'.create') mc.delete(tempTr) orderedTrs=[] orderedCtrls=[] if self.distribute not in ['u','v']: #calculate the axis of distribution if len(self.trs)!=0: mc.connectAttr(self.surfaceAttr,cpos+'.inputSurface') uMin=100 vMin=100 uMax=0 vMax=0 uPosList=[] vPosList=[] for i in range(0,self.number): orderedTrs.append('') orderedCtrls.append('') t=self.trs[i] if mc.objExists(t): # find the closest point if self.hasGeometry: center=mc.objectCenter(t) mc.setAttr(cpos+'.ip',*center) posCenter,uCenter,vCenter=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') rp=mc.xform(t,ws=True,q=True,rp=True) mc.setAttr(cpos+'.ip',*rp) posRP,uRP,vRP=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') # see which is closer - object center or rotate pivot if self.hasGeometry: distCenter=distanceBetween(posCenter,center) distRP=distanceBetween(posRP,rp) if self.hasGeometry==False or abs(distCenter)>abs(distRP) : uPosList.append(uRP) vPosList.append(vRP) if uRP<uMin: uMin=uRP if uRP>uMax: uMax=uRP if vRP<vMin: vMin=vRP if vRP>vMax: vMax=vRP else: uPosList.append(uCenter) vPosList.append(vCenter) if uCenter<uMin: uMin=uCenter if uCenter>uMax: uMax=uCenter if vCenter<vMin: vMin=vCenter if vCenter>vMax: vMax=vCenter cfsi=mc.createNode('curveFromSurfaceIso') mc.connectAttr(self.surfaceAttr,cfsi+'.is') mc.setAttr(cfsi+'.idr',0) mc.setAttr(cfsi+'.iv',.5) mc.setAttr(cfsi+'.r',True) mc.setAttr(cfsi+'.rv',True) if len(self.trs)!=0: mc.setAttr(cfsi+'.min',uMin) mc.setAttr(cfsi+'.max',uMax) ci=mc.createNode('curveInfo') mc.connectAttr(cfsi+'.oc',ci+'.ic') uLength=mc.getAttr(ci+'.al') mc.setAttr(cfsi+'.idr',1) if len(self.trs)!=0: mc.setAttr(cfsi+'.min',vMin) mc.setAttr(cfsi+'.max',vMax) vLength=mc.getAttr(ci+'.al') mc.delete(cfsi,ci) if uLength>vLength: self.distribute='u' if len(self.trs)!=0: searchList=uPosList orderedList=uPosList[:] orderedList.sort() else: self.distribute='v' if len(self.trs)!=0: searchList=vPosList orderedList=vPosList[:] orderedList.sort() reverseTrs=False orderIDList=[] for n in range(0,self.number): s=searchList[n] for i in range(0,self.number): if s==orderedList[i] and i not in orderIDList: orderIDList.append(i) orderedTrs[i]=self.trs[n] orderedCtrls[i]=self.ctrls[n] if n==0 and i>len(self.trs)/2: reverseTrs=True break if reverseTrs: orderedTrs.reverse() self.trs=orderedTrs orderedCtrls.reverse() self.ctrls=orderedCtrls else: self.trs=orderedTrs self.ctrls=orderedCtrls if self.rebuild: # interactive rebuild, maintains even parameterization over the rivet surface, use with caution if self.distribute=='u': self.surfaceAttr=mel.eval('zenUniformSurfaceRebuild("'+self.surfaceAttr+'",'+str(self.uSpans*2)+',-1)')+'.outputSurface' else: self.surfaceAttr=mel.eval('zenUniformSurfaceRebuild("'+self.surfaceAttr+'",-1,'+str(self.vSpans*2)+')')+'.outputSurface' if not mc.isConnected(self.surfaceAttr,cpos+'.inputSurface'): mc.connectAttr(self.surfaceAttr,cpos+'.inputSurface',f=True) if self.taper=='distance' or self.createAimCurve or self.closestPoint=='geometry': # find the closest points ( and antipodes ) for i in range(0,self.number): t=self.trs[i] cp=ClosestPoints(self.surfaceAttr,t) self.ClosestPoints.append(cp) if self.taper=='distance' or self.createAimCurve: # antipodes are used for lattice allignment and curve calculations antipodes.append(cp.getAntipodes(1)) if self.taper!='none' or self.scale!='none': # measures scale with scaling cfsiLength=mc.createNode('curveFromSurfaceIso') ciLength=mc.createNode('curveInfo') lengthMultiplierNode=mc.createNode('multDoubleLinear') mc.setAttr(cfsiLength+'.relative',True) mc.setAttr(cfsiLength+'.relativeValue',True) if self.distribute=='u': mc.setAttr(cfsiLength+'.isoparmDirection',0) else: mc.setAttr(cfsiLength+'.isoparmDirection',1) mc.setAttr(cfsiLength+'.minValue',0) mc.setAttr(cfsiLength+'.maxValue',1) mc.setAttr(cfsiLength+".isoparmValue",.5) mc.connectAttr(self.surfaceAttr,cfsiLength+'.inputSurface') if mc.objExists(self.spaceTr): lengthCurve=mc.createNode('nurbsCurve',p=self.spaceTr) lengthCurveTG=mc.createNode('transformGeometry') mc.connectAttr(self.spaceTr+'.worldMatrix[0]',lengthCurveTG+'.txf') mc.connectAttr(cfsiLength+'.outputCurve',lengthCurveTG+'.ig') mc.connectAttr(lengthCurveTG+'.og',lengthCurve+'.create') mc.connectAttr(lengthCurve+'.worldSpace',ciLength+'.inputCurve') mc.setAttr(lengthCurve+'.intermediateObject',True) cleanup.extend([lengthCurveTG,cfsiLength]) else: mc.connectAttr(cfsiLength+'.outputCurve',ciLength+'.inputCurve') mc.connectAttr(ciLength+'.al',lengthMultiplierNode+'.i1') mc.setAttr(lengthMultiplierNode+'.i2',1.0/float(mc.getAttr(ciLength+'.al'))) lengthMultiplier=lengthMultiplierNode+'.o' uvPos=[] closestDistanceToCenter=Decimal('infinity') centerMostRivetID=0 closestDistancesToCenter=[Decimal('infinity'),Decimal('infinity')] centerMostRivetIDs=[0,0] uvMultipliers=[] aimGroups=[] for i in range(0,self.number): pTrs=mc.listRelatives(self.trs[i],p=True) parentTr='' if len(iterable(pTrs))>0: parentTr=pTrs[0] t=self.trs[i] c=self.ctrls[i] r=mc.createNode('transform',n='Rivet#') wsMatrices.append(mc.xform(t,q=True,ws=True,m=True)) if self.constraint: mc.setAttr(r+'.inheritsTransform',False) if not mc.objExists(c): c=t if not mc.objExists(t): c=r if not mc.objExists(c+'.zenRivet'): mc.addAttr(c,at='message',ln='zenRivet',sn='zriv') mc.connectAttr(r+'.message',c+'.zriv',f=True) if not mc.objExists(c+'.uPos'): mc.addAttr(c,k=True,at='double',ln='uPos',dv=50) if not mc.objExists(c+'.vPos'): mc.addAttr(c,k=True,at='double',ln='vPos',dv=50) if self.closestPoint=='geometry': up,vp=self.ClosestPoints[i].uvs[0] else: if mc.objExists(t): if self.hasGeometry: center=mc.objectCenter(t) mc.setAttr(cpos+'.ip',*center) posCenter,uCenter,vCenter=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') rp=mc.xform(t,ws=True,q=True,rp=True) mc.setAttr(cpos+'.ip',*rp) posRP,uRP,vRP=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') if self.hasGeometry: distCenter=distanceBetween(posCenter,center) distRP=distanceBetween(posRP,rp) if self.hasGeometry==False or abs(distCenter)>abs(distRP): up=uRP vp=vRP else: up=uCenter vp=vCenter elif len(distribute)>0: if self.distribute=='u': up=(i+1)/self.number vp=.5 else: up=.5 vp=(i+1)/self.number if up>float(self.uSpans)-.01: up=float(self.uSpans)-.01 if vp>float(self.vSpans)-.01: vp=float(self.vSpans)-.01 if up<.01: up=.01 if vp<.01: vp=.01 uvPos.append((up,vp)) if up<.5 and self.distribute=='u' and Decimal(str(abs(.5-up)))<Decimal(str(closestDistancesToCenter[0])): closestDistancesToCenter[0]=abs(.5-up) centerMostRivetIDs[0]=i if up>.5 and self.distribute=='u' and Decimal(str(abs(.5-up)))<Decimal(str(closestDistancesToCenter[1])): closestDistancesToCenter[1]=abs(.5-up) centerMostRivetIDs[1]=i if up<.5 and self.distribute=='v' and Decimal(str(abs(.5-vp)))<Decimal(str(closestDistancesToCenter[0])): closestDistancesToCenter[0]=abs(.5-vp) centerMostRivetIDs[0]=i if up>.5 and self.distribute=='v' and Decimal(str(abs(.5-vp)))<Decimal(str(closestDistancesToCenter[1])): closestDistancesToCenter[1]=abs(.5-vp) centerMostRivetIDs[1]=i mc.setAttr(c+'.uPos',up*100) mc.setAttr(c+'.vPos',vp*100) posi=mc.createNode('pointOnSurfaceInfo') mc.setAttr((posi+".caching"),True) #mc.setAttr((posi+".top"),True) multiplyU=mc.createNode('multDoubleLinear') mc.connectAttr(c+".uPos",multiplyU+".i1") mc.setAttr(multiplyU+'.i2',.01) multiplyV=mc.createNode('multDoubleLinear') mc.connectAttr(c+".vPos",multiplyV+".i1") mc.setAttr(multiplyV+'.i2',.01) uvMultipliers.append([multiplyU,multiplyV]) mc.connectAttr(self.surfaceAttr,posi+".inputSurface"); mc.connectAttr(multiplyU+".o",posi+".parameterU") mc.connectAttr(multiplyV+".o",posi+".parameterV") dm=mc.createNode('decomposeMatrix') mc.setAttr(dm+'.caching',True) fbfm=mc.createNode('fourByFourMatrix') mc.setAttr(fbfm+'.caching',True) mc.connectAttr(posi+'.nnx',fbfm+'.in00') mc.connectAttr(posi+'.nny',fbfm+'.in01') mc.connectAttr(posi+'.nnz',fbfm+'.in02') mc.connectAttr(posi+'.nux',fbfm+'.in10') mc.connectAttr(posi+'.nuy',fbfm+'.in11') mc.connectAttr(posi+'.nuz',fbfm+'.in12') mc.connectAttr(posi+'.nvx',fbfm+'.in20') mc.connectAttr(posi+'.nvy',fbfm+'.in21') mc.connectAttr(posi+'.nvz',fbfm+'.in22') mc.connectAttr(posi+'.px',fbfm+'.in30') mc.connectAttr(posi+'.py',fbfm+'.in31') mc.connectAttr(posi+'.pz',fbfm+'.in32') if self.constraint:# and not self.parent: mc.connectAttr(fbfm+'.output',dm+'.inputMatrix') else: multMatrix=mc.createNode('multMatrix') mc.connectAttr(r+'.parentInverseMatrix',multMatrix+'.i[1]') mc.connectAttr(fbfm+'.output',multMatrix+'.i[0]') mc.connectAttr(multMatrix+'.o',dm+'.inputMatrix') mc.connectAttr(dm+'.outputTranslate',r+'.t') mc.connectAttr(dm+'.outputRotate',r+'.r') if t!=r: if self.createAimCurve: aimGroup=mc.createNode('transform',n='rivetAimGrp#') mc.parent(aimGroup,t,r=True) mc.parent(aimGroup,r) if self.keepPivot or self.closestPoint=='pivot': mc.xform(aimGroup,ws=True,piv=mc.xform(t,q=True,ws=True,rp=True)) else: mc.xform(aimGroup,ws=True,piv=self.ClosestPoints[i][1]) self.aimGroups.append(aimGroup) if self.constraint: if self.parent: # parent and constraint == ParentSpace self.parentSpaces.append(ParentSpace(t,r)) pc=self.parentSpaces[i].parentConstraint sc=self.parentSpaces[i].scaleConstraint skip=['x'] if\ ( (self.distribute=='v' and 'length' in self.scaleDirection) or (self.distribute=='u' and 'width' in self.scaleDirection) or t in self.skipScaleObjects ): skip.append('y') if\ ( (self.distribute=='u' and 'length' in self.scaleDirection) or (self.distribute=='v' and 'width' in self.scaleDirection) or t in self.skipScaleObjects ): skip.append('z') mc.scaleConstraint(sc,e=True,sk=skip) if t in self.skipRotateObjects: mc.parentConstraint(pc,e=True,sr=('x','y','z')) if t in self.skipTranslateObjects: mc.parentConstraint(pc,e=True,st=('x','y','z')) else: #just constraint if t in self.skipRotateObjects: pc=mc.parentConstraint(r,t,sr=('x','y','z'),mo=True)[0]# if t in self.skipTranslateObjects: pc=mc.parentConstraint(r,t,st=('x','y','z'),mo=self.mo)[0] if t not in self.skipRotateObjects and t not in self.skipTranslateObjects: pc=mc.parentConstraint(r,t,mo=self.mo)[0] pcTargets=mc.parentConstraint(pc,q=True,tl=True) pcIDs=[] nsc=listNodeConnections(r,pc,s=False,d=True) for n in range(0,len(nsc)): if len(nsc[n])==2 and mc.objExists(nsc[n][-1]): pcID=getIDs(nsc[n][-1]) if isinstance(pcID,int): pcIDs.append(pcID) pcIDs=removeDuplicates(pcIDs) for pcID in pcIDs: mc.connectAttr(self.worldMatrix,pc+'.tg['+str(pcID)+'].tpm',f=True) mc.connectAttr(dm+'.outputTranslate',pc+'.tg['+str(pcID)+'].tt',f=True) mc.connectAttr(dm+'.outputRotate',pc+'.tg['+str(pcID)+'].tr',f=True) cleanup.append(r) if self.parent: scTargets=mc.scaleConstraint(sc,q=True,tl=True) scIDs=[] nsc=listNodeConnections(r,sc,s=False,d=True) for n in range(0,len(nsc)): if len(nsc[n])==2 and mc.objExists(nsc[n][-1]): scIDs.append(getIDs(nsc[n][-1])) scIDs=removeDuplicates(scIDs) scMD=mc.createNode('multiplyDivide') mc.setAttr(scMD+'.i1',1,1,1) mc.setAttr(scMD+'.i2',1,1,1) for scID in scIDs: mc.connectAttr(self.worldMatrix,sc+'.tg['+str(scID)+'].tpm',f=True) #mc.connectAttr(scMD+'.o',sc+'.tg['+str(scID)+'].ts',f=True) mc.connectAttr(scMD+'.ox',sc+'.tg['+str(scID)+'].tsx',f=True) mc.connectAttr(scMD+'.oy',sc+'.tg['+str(scID)+'].tsy',f=True) mc.connectAttr(scMD+'.oz',sc+'.tg['+str(scID)+'].tsz',f=True) r=self.parentSpaces[i][0] #xfm=mc.xform(r,q=True,ws=True,m=True) #mc.setAttr(r+'.inheritsTransform',False) #mc.xform(r,m=xfm) #mc.connectAttr(self.surfaceMatrix,multMatrix+'.i[1]',f=True)#self.parentSpaces[i][0]+'.parentInverseMatrix' elif self.createAimCurve: mc.parent(t,w=True) mc.setAttr(t+'.inheritsTransform',False) mc.parent(t,r,r=True) else: mc.parent(t,r) if mc.objExists(parentTr) and (self.parent or self.createAimCurve) and not self.constraint: if not (parentTr in iterable(mc.listRelatives(r,p=True))): if mc.getAttr(r+'.inheritsTransform')==True: mc.parent(r,parentTr,r=True) else: mc.parent(r,parentTr) if mc.getAttr(r+'.inheritsTransform')==False: dm=mc.createNode('decomposeMatrix') mc.connectAttr(parentTr+'.worldMatrix',dm+'.inputMatrix') mc.connectAttr(dm+'.os',t+'.s',f=True) if self.taper!='none' or self.scale!='none': cfsiU=mc.createNode('curveFromSurfaceIso') mc.setAttr(cfsiU+'.relative',True) mc.setAttr(cfsiU+'.relativeValue',True) mc.setAttr(cfsiU+'.isoparmDirection',0) mc.setAttr(cfsiU+'.minValue',0) mc.setAttr(cfsiU+'.maxValue',1) mc.connectAttr(multiplyV+".o",cfsiU+".isoparmValue") mc.connectAttr(self.surfaceAttr,cfsiU+'.inputSurface') cfsiV=mc.createNode('curveFromSurfaceIso') mc.setAttr(cfsiV+'.relative',True) mc.setAttr(cfsiV+'.relativeValue',True) mc.setAttr(cfsiV+'.isoparmDirection',1) mc.setAttr(cfsiV+'.minValue',0) mc.setAttr(cfsiV+'.maxValue',1) mc.connectAttr(multiplyV+".o",cfsiV+".isoparmValue") mc.connectAttr(self.surfaceAttr,cfsiV+'.inputSurface') subtractNode=mc.createNode('addDoubleLinear') mc.setAttr(subtractNode+'.i1',-(1/(self.number*2))) addNode=mc.createNode('addDoubleLinear') mc.setAttr(addNode+'.i1',1/(self.number*2)) addSubClampNode=mc.createNode('clamp') mc.setAttr(addSubClampNode+'.min',0,0,0) mc.setAttr(addSubClampNode+'.max',1,1,1) mc.connectAttr(subtractNode+'.o',addSubClampNode+'.inputR') mc.connectAttr(addNode+'.o',addSubClampNode+'.inputG') if self.distribute=='u': mc.connectAttr(multiplyU+".o",subtractNode+".i2") mc.connectAttr(multiplyU+".o",addNode+".i2") mc.connectAttr(addSubClampNode+'.outputR',cfsiU+'.minValue') mc.connectAttr(addSubClampNode+'.outputG',cfsiU+'.maxValue') else: mc.connectAttr(multiplyV+".o",subtractNode+".i2") mc.connectAttr(multiplyV+".o",addNode+".i2") mc.connectAttr(addSubClampNode+'.outputR',cfsiV+'.minValue') mc.connectAttr(addSubClampNode+'.outputG',cfsiV+'.maxValue') ciU=mc.createNode('curveInfo') mc.connectAttr(cfsiU+'.outputCurve',ciU+'.inputCurve') ciV=mc.createNode('curveInfo') mc.connectAttr(cfsiV+'.outputCurve',ciV+'.inputCurve') mdlU=mc.createNode('multDoubleLinear') mc.connectAttr(ciU+'.al',mdlU+'.i1') mc.setAttr(mdlU+'.i2',1/float(mc.getAttr(ciU+'.al'))) mdlV=mc.createNode('multDoubleLinear') mc.connectAttr(ciV+'.al',mdlV+'.i1') mc.setAttr(mdlV+'.i2',1/float(mc.getAttr(ciV+'.al'))) if not mc.objExists(c+'.minScaleWidth'): mc.addAttr(c,ln='minScaleWidth',at='double',k=True,min=0,dv=self.minScaleWidth) if not mc.objExists(c+'.maxScaleWidth'): mc.addAttr(c,ln='maxScaleWidth',at='double',k=True,min=0,dv=self.maxScaleWidth) if not mc.objExists(c+'.minScaleLength'): mc.addAttr(c,ln='minScaleLength',at='double',k=True,min=0,dv=self.minScaleLength) if not mc.objExists(c+'.maxScaleLength'): mc.addAttr(c,ln='maxScaleLength',at='double',k=True,min=0,dv=self.maxScaleLength) clampNode=mc.createNode('clamp') minScaleLengthNode=mc.createNode('multDoubleLinear') maxScaleLengthNode=mc.createNode('multDoubleLinear') minScaleWidthNode=mc.createNode('multDoubleLinear') maxScaleWidthNode=mc.createNode('multDoubleLinear') mc.connectAttr(c+'.minScaleLength',minScaleLengthNode+'.i1') mc.connectAttr(lengthMultiplier,minScaleLengthNode+'.i2') mc.connectAttr(c+'.maxScaleLength',maxScaleLengthNode+'.i1') mc.connectAttr(lengthMultiplier,maxScaleLengthNode+'.i2') mc.connectAttr(c+'.minScaleWidth',minScaleWidthNode+'.i1') mc.connectAttr(lengthMultiplier,minScaleWidthNode+'.i2') mc.connectAttr(c+'.maxScaleWidth',maxScaleWidthNode+'.i1') mc.connectAttr(lengthMultiplier,maxScaleWidthNode+'.i2') if self.distribute=='u': mc.connectAttr(minScaleLengthNode+'.o',clampNode+'.minR') mc.connectAttr(maxScaleLengthNode+'.o',clampNode+'.maxR') mc.connectAttr(minScaleWidthNode+'.o',clampNode+'.minG') mc.connectAttr(maxScaleWidthNode+'.o',clampNode+'.maxG') else: mc.connectAttr(minScaleWidthNode+'.o',clampNode+'.minR') mc.connectAttr(maxScaleWidthNode+'.o',clampNode+'.maxR') mc.connectAttr(minScaleLengthNode+'.o',clampNode+'.minG') mc.connectAttr(maxScaleLengthNode+'.o',clampNode+'.maxG') mc.connectAttr(mdlU+'.o',clampNode+'.ipr') mc.connectAttr(mdlV+'.o',clampNode+'.ipg') if self.scale=='relative' and self.parent:#or len(self.scaleDirection)<2:# if\ ( (self.distribute=='u' and 'length' in self.scaleDirection) or (self.distribute=='v' and 'width' in self.scaleDirection) ): if self.constraint: mc.connectAttr(clampNode+'.opr',scMD+'.i1y') else: mc.connectAttr(clampNode+'.opr',r+'.sy',f=True) if\ ( (self.distribute=='v' and 'length' in self.scaleDirection) or (self.distribute=='u' and 'width' in self.scaleDirection) ): if self.constraint: mc.connectAttr(clampNode+'.opg',scMD+'.i1z') else: mc.connectAttr(clampNode+'.opg',r+'.sz',f=True) elif self.taper!='none' and self.parent: #self.autoFlexGroups mc.setAttr(t+'.sx',lock=True) mc.setAttr(t+'.sy',lock=True) mc.setAttr(t+'.sz',lock=True) mc.setAttr(t+'.tx',lock=True) mc.setAttr(t+'.ty',lock=True) mc.setAttr(t+'.tz',lock=True) mc.setAttr(t+'.rx',lock=True) mc.setAttr(t+'.ry',lock=True) mc.setAttr(t+'.rz',lock=True) aimTr=mc.createNode('transform',p=t) mc.xform(aimTr,ws=True,t=antipodes[i]) #mc.setAttr(db+'.p1',*self.ClosestPoints[i][0]) #mc.setAttr(db+'.p2',*antipodes[i]) axisLength=distanceBetween(self.ClosestPoints[i][0],antipodes[i])#mc.getAttr(db+'.d') ffd,lattice,latticeBase=mc.lattice(t,divisions=(2,2,2),objectCentered=True,ol=1) latticeLowEndPoints=mc.ls(lattice+'.pt[0:1][0:0][0:1]',fl=True) latticeHighEndPoints=mc.ls(lattice+'.pt[0:1][1:1][0:1]',fl=True) mc.parent(latticeBase,lattice) mc.setAttr(lattice+'.sy',axisLength) lattices.append([ffd,lattice,latticeBase]) mc.parent(lattice,t) mc.xform(lattice,ws=True,a=True,t=mc.xform(r,q=True,ws=True,a=True,rp=True)) mc.xform(lattice,os=True,a=True,ro=(0,0,0)) mc.move(0,axisLength/2,0,lattice,r=True,os=True,wd=True) xSum,ySum,zSum=0,0,0 for p in latticeLowEndPoints: px,py,pz=mc.pointPosition(p,w=True) xSum+=px ySum+=py zSum+=pz mc.xform(lattice,ws=True,piv=(xSum/len(latticeLowEndPoints),ySum/len(latticeLowEndPoints),zSum/len(latticeLowEndPoints))) mc.xform(latticeBase,ws=True,piv=(xSum/len(latticeLowEndPoints),ySum/len(latticeLowEndPoints),zSum/len(latticeLowEndPoints))) ac=mc.aimConstraint(aimTr,lattice,aim=(0,1,0),wut='objectrotation',wuo=r,u=(0,0,1),mo=False) mc.delete(ac) ac=mc.aimConstraint(aimTr,aimGroup,aim=(0,1,0),wut='objectrotation',wuo=r,u=(0,0,1),mo=False) mc.delete(ac,aimTr) lowEndCluster,lowEndClusterHandle=mc.cluster(latticeLowEndPoints)[:2] highEndCluster,highEndClusterHandle=mc.cluster(latticeHighEndPoints)[:2] lowEndClusterHandleShape=mc.listRelatives(lowEndClusterHandle,c=True)[0] highEndClusterHandleShape=mc.listRelatives(highEndClusterHandle,c=True)[0] #mc.parent(highEndClusterHandle,t) if mc.isConnected(lowEndClusterHandleShape+'.clusterTransforms[0]',lowEndCluster+'.clusterXforms'): mc.disconnectAttr(lowEndClusterHandleShape+'.clusterTransforms[0]',lowEndCluster+'.clusterXforms') if mc.isConnected(highEndClusterHandleShape+'.clusterTransforms[0]',highEndCluster+'.clusterXforms'): mc.disconnectAttr(highEndClusterHandleShape+'.clusterTransforms[0]',highEndCluster+'.clusterXforms') self.autoFlexGroups.append\ ( ( mc.createNode('transform',n='rivetBaseAutoFlex#',p=r), mc.createNode('transform',n='rivetEndAutoFlex#',p=aimGroup) ) ) self.handles.append\ ( ( mc.createNode('transform',n='rivetBaseCtrl#',p=self.autoFlexGroups[i][0]), mc.createNode('transform',n='rivetEndCtrl#',p=self.autoFlexGroups[i][1]) ) ) self.handleShapes.append\ ( ( mc.createNode('locator',p=self.handles[i][0]), mc.createNode('locator',p=self.handles[i][1]) ) ) mc.setAttr(self.handleShapes[i][0]+'.los',.5,.5,.5) mc.setAttr(self.handleShapes[i][1]+'.los',.5,.5,.5) mc.xform(self.autoFlexGroups[i][0],ws=True,a=True,t=mc.xform(t,q=True,ws=True,rp=True)) mc.xform(self.autoFlexGroups[i][0],ws=True,a=True,piv=mc.xform(t,q=True,ws=True,rp=True)) for bp in self.bindPoses: mc.dagPose((self.handles[i][0],self.handles[i][1]),a=True,n=bp) mc.xform(self.autoFlexGroups[i][1],ws=True,t=antipodes[i]) mc.hide(lattice) mc.connectAttr(self.handles[i][0]+'.worldInverseMatrix[0]',lowEndCluster+'.bindPreMatrix',f=True) mc.disconnectAttr(self.handles[i][0]+'.worldInverseMatrix[0]',lowEndCluster+'.bindPreMatrix') mc.connectAttr(self.handles[i][0]+'.worldMatrix[0]',lowEndCluster+'.matrix',f=True) mc.connectAttr(self.handles[i][1]+'.worldInverseMatrix[0]',highEndCluster+'.bindPreMatrix',f=True) mc.disconnectAttr(self.handles[i][1]+'.worldInverseMatrix[0]',highEndCluster+'.bindPreMatrix') mc.connectAttr(self.handles[i][1]+'.worldMatrix[0]',highEndCluster+'.matrix',f=True) aimGroups.append(aimGroup) if self.distribute=='u': mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][0]+'.sy') else: mc.connectAttr(clampNode+'.opg',self.autoFlexGroups[i][0]+'.sz') mc.delete([lowEndClusterHandle,highEndClusterHandle]) self.rivets.append(r) if self.createAimCurve and self.parent: pmm=mc.createNode('pointMatrixMult') arcPoints=[] ids=[0,centerMostRivetIDs[0],centerMostRivetIDs[1],-1] for id in ids: measureTr=mc.createNode('transform') aimTr=mc.createNode('transform',p=self.trs[id]) mc.parent(measureTr,self.trs[id]) mc.xform(aimTr,ws=True,t=antipodes[id]) mc.xform(measureTr,ws=True,t=mc.xform(self.rivets[id],q=True,ws=True,a=True,rp=True)) #mc.xform(measureTr,os=True,a=True,ro=(0,0,0),s=(1,1,1)) ac=mc.aimConstraint(aimTr,measureTr,aim=(0,1,0),wut='objectrotation',wuo=self.rivets[id],u=(0,0,1),mo=False) mc.delete(ac,aimTr) mc.connectAttr(measureTr+'.worldInverseMatrix',pmm+'.inMatrix',f=True) maxYID=-1 maxY=0.0 yVal=0.0 for i in range(0,self.number): mc.setAttr(pmm+'.ip',*antipodes[i]) yVal=mc.getAttr(pmm+'.oy') if yVal>maxY: maxY=yVal maxYID=i mc.setAttr(pmm+'.ip',*antipodes[maxYID]) oy=mc.getAttr(pmm+'.oy') mc.setAttr(pmm+'.ip',*antipodes[id]) ox=mc.getAttr(pmm+'.ox') oz=mc.getAttr(pmm+'.oz') mc.connectAttr(measureTr+'.worldMatrix',pmm+'.inMatrix',f=True) mc.setAttr(pmm+'.ip',ox,oy,oz) ap=mc.getAttr(pmm+'.o')[0] arcPoints.append(ap) mc.disconnectAttr(measureTr+'.worldMatrix',pmm+'.inMatrix') mc.delete(measureTr) mc.delete(pmm) arcCtrlArg=arcPoints arcCtrlKeys={'arcWeight':self.arcWeight,'p':self.parents,'sp':self.softParents} for k in arcCtrlKeys: if type(arcCtrlKeys[k]).__name__=='NoneType': del(arcCtrlKeys[k]) self.ArcCtrl=ArcCtrl(*arcCtrlArg,**arcCtrlKeys) mc.addAttr(self.ArcCtrl[0],at='bool',ln='showHandles',k=True,dv=False) mc.setAttr(self.ArcCtrl[0]+'.showHandles',k=False,cb=True) mc.setAttr(self.ArcCtrl[0]+'.v',k=False,cb=True) mc.setAttr(self.ArcCtrl[1]+'.v',k=False,cb=True) for h in self.handles: mc.connectAttr(self.ArcCtrl[0]+'.showHandles',h[0]+'.v') mc.connectAttr(self.ArcCtrl[0]+'.showHandles',h[1]+'.v') for bp in self.bindPoses: mc.dagPose(self.ArcCtrl,a=True,n=bp) cpoc=mc.createNode('closestPointOnCurve') mc.connectAttr(self.ArcCtrl.outputCurve,cpoc+'.inCurve') for i in range(0,self.number): aimTr=mc.createNode('transform') poci=mc.createNode('pointOnCurveInfo') dm=mc.createNode('decomposeMatrix') fbfm=mc.createNode('fourByFourMatrix') mc.connectAttr(poci+'.nnx',fbfm+'.in00') mc.connectAttr(poci+'.nny',fbfm+'.in01') mc.connectAttr(poci+'.nnz',fbfm+'.in02') mc.connectAttr(poci+'.ntx',fbfm+'.in10') mc.connectAttr(poci+'.nty',fbfm+'.in11') mc.connectAttr(poci+'.ntz',fbfm+'.in12') mc.connectAttr(self.ArcCtrl.outputNormal+'X',fbfm+'.in20') mc.connectAttr(self.ArcCtrl.outputNormal+'Y',fbfm+'.in21') mc.connectAttr(self.ArcCtrl.outputNormal+'Z',fbfm+'.in22') mc.connectAttr(poci+'.px',fbfm+'.in30') mc.connectAttr(poci+'.py',fbfm+'.in31') mc.connectAttr(poci+'.pz',fbfm+'.in32') mc.connectAttr(fbfm+'.output',dm+'.inputMatrix') mc.connectAttr(dm+'.outputTranslate',aimTr+'.t') mc.connectAttr(dm+'.outputRotate',aimTr+'.r') mc.setAttr(cpoc+'.ip',*antipodes[i]) cpu=mc.getAttr(cpoc+'.u') mc.setAttr(poci+'.parameter',cpu) mc.connectAttr(self.ArcCtrl.outputCurve,poci+'.inputCurve') ac=mc.aimConstraint(aimTr,self.aimGroups[i],aim=(0,1,0),wut='objectrotation',wuo=aimTr,u=(0,0,1),mo=not(self.realign))[0] disconnectNodes(aimTr,ac) mc.connectAttr(fbfm+'.output',ac+'.worldUpMatrix',f=True) mc.connectAttr(dm+'.ot',ac+'.target[0].targetTranslate',f=True) mc.delete(aimTr) sc=mc.createNode('subCurve') mc.setAttr(sc+'.relative',True) mc.setAttr(sc+'.minValue',0) mc.setAttr(sc+'.maxValue',1) mc.connectAttr(self.ArcCtrl.outputCurve,sc+'.ic') if self.distribute=='u': uMultAttr=uvMultipliers[i][0]+".o" else: uMultAttr=uvMultipliers[i][1]+".o" #adjust for offset multOffsetCalc=mc.createNode('multDoubleLinear') mc.setAttr(multOffsetCalc+'.i1',1/mc.getAttr(uMultAttr)) mc.connectAttr(uMultAttr,multOffsetCalc+'.i2') multOffset=mc.createNode('multDoubleLinear') mc.setAttr(multOffset+'.i1',cpu) mc.connectAttr(multOffsetCalc+'.o',multOffset+'.i2') mc.connectAttr(multOffset+'.o',poci+'.parameter',f=True) subtractNode=mc.createNode('addDoubleLinear') mc.setAttr(subtractNode+'.i1',-(1.0/(self.number*2))) addNode=mc.createNode('addDoubleLinear') mc.setAttr(addNode+'.i1',1.0/(self.number*2)) addSubClampNode=mc.createNode('clamp') mc.setAttr(addSubClampNode+'.min',0,0,0) mc.setAttr(addSubClampNode+'.max',1,1,1) mc.connectAttr(subtractNode+'.o',addSubClampNode+'.inputR') mc.connectAttr(addNode+'.o',addSubClampNode+'.inputG') mc.connectAttr(multOffset+".o",subtractNode+".i2") mc.connectAttr(multOffset+".o",addNode+".i2") mc.connectAttr(addSubClampNode+'.outputR',sc+'.minValue') mc.connectAttr(addSubClampNode+'.outputG',sc+'.maxValue') ciU=mc.createNode('curveInfo') mc.connectAttr(sc+'.outputCurve',ciU+'.inputCurve') mdlU=mc.createNode('multDoubleLinear') mc.connectAttr(ciU+'.al',mdlU+'.i1') mc.setAttr(mdlU+'.i2',1/float(mc.getAttr(ciU+'.al'))) clampNode=mc.createNode('clamp') if not mc.objExists(c+'.minScaleEnd'): mc.addAttr(self.ctrls[i],ln='minScaleEnd',at='double',k=True,min=0,max=1,dv=0) if not mc.objExists(c+'.maxScaleEnd'): mc.addAttr(self.ctrls[i],ln='maxScaleEnd',at='double',k=True,min=0,dv=1) mc.connectAttr(self.ctrls[i]+'.minScaleEnd',clampNode+'.minR') mc.connectAttr(self.ctrls[i]+'.maxScaleEnd',clampNode+'.maxR') mc.connectAttr(mdlU+'.o',clampNode+'.ipr') if self.distribute=='u': mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][1]+'.sz') else: mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][1]+'.sy') mc.delete(cpoc) if self.parent: self[:]=self.rivets else: self[:]=self.trs #if self.mo: # #for i in len(self.trs): # #try: mc.xform(t,q=True,ws=True,m=wsMatrices[i])) # #except: pass cleanup.append(cpos) for c in cleanup: if mc.objExists(c): disconnectNodes(c) mc.delete(c) if self.snapToSurface: if self.createAimCurve or self.taper: for i in range(0,self.number): mc.xform(self.handles[i][0],ws=True,t=mc.xform(self.rivets[i],q=True,ws=True,rp=True)) mc.xform(self.trs[i],ws=True,rp=mc.xform(self.rivets[i],q=True,ws=True,rp=True)) else: for i in range(0,self.number): mc.xform(self.trs[i],ws=True,t=mc.xform(self.rivets[i],q=True,ws=True,rp=True)) mc.xform(self.trs[i],ws=True,ro=mc.xform(self.rivets[i],q=True,ws=True,ro=True))
def create(self): mc.cycleCheck(e=False) if mc.objExists(self.parent): self.group=mc.createNode('transform',n=uniqueNames(self.name),p=self.parent) else: self.group=mc.createNode('transform',n=uniqueNames(self.name)) self.jointParent='' if len(iterable(mc.listRelatives(self.joints[0],p=True)))>0: self.jointParent=mc.listRelatives(self.joints[0],p=True)[0] else: self.jointParent=mc.createNode('transform',n=uniqueNames(self.name+'CtrlJointGroup')) mc.parent(self.joints[0],self.jointParent) cMuscleObjects=[] # create control joints self.ctrlJoints=[] for j in self.joints: cj=mc.createNode('joint',p=j,n=uniqueNames(self.name+'CtrlJoint')) if len(self.ctrlJoints)==0: mc.parent(cj,self.group) if mc.objExists(self.jointParent): self.jointParent=mc.rename(ParentSpace(cj,self.jointParent)[0],self.name+'CtrlJoints') else: self.jointParent=mc.rename(ParentSpace(cj)[0],self.name+'CtrlJoints') else: mc.parent(cj,self.ctrlJoints[-1]) mc.setAttr(cj+'.r',*mc.getAttr(j+'.r')[0]) mc.setAttr(cj+'.jo',*mc.getAttr(j+'.jo')[0]) self.originalRotations[cj+'.r']=list(mc.getAttr(cj+'.r')[0]) mc.setAttr(j+'.r',0,0,0) mc.setAttr(cj+'.r',0,0,0) mc.setAttr(cj+'.s',1,1,1) mc.setAttr(cj+'.radius',mc.getAttr(j+'.radius')*1.5)#0) mc.setAttr(cj+'.ovc',10) mc.connectAttr(j+'.pa',cj+'.pa') if self.joints.index(j)<len(self.joints)-1: childList=removeAll\ ( iterable(mc.listRelatives(self.joints[self.joints.index(j)+1],c=True,ad=True))+[self.joints[self.joints.index(j)+1]], iterable(mc.listRelatives(j,c=True,ad=True))+[j] ) chList=childList for c in chList: if mc.nodeType(c) not in ['transform','joint','cMuscleObject']: childList.remove(c) if mc.nodeType(c) in ['transform','joint']: for a in ['.t','.tx','.ty','.tz','.r','.rx','.ry','.rz']: if mc.connectionInfo(c+a,id=True) or mc.getAttr(c+a,l=True) or mc.getAttr(c+'.io'): childList.remove(c) break if j==self.joints[-2]: childList.append(self.joints[-1]) for jc in childList: if mc.nodeType(jc)=='transform' or mc.nodeType(jc)=='joint': if jc in self.joints[:-1]: mc.parentConstraint(cj,jc,mo=True) else: mc.parentConstraint(cj,jc,sr=('x','y','z'),mo=True) elif 'cMuscle' in mc.nodeType(jc): cMuscleObjects.append(jc) else: mc.parentConstraint(cj,j,st=('x','y','z'),mo=True) self.ctrlJoints.append(cj) mc.hide(self.jointParent) mc.setAttr(self.ctrlJoints[1]+'.ssc',False) # create ik self.ikHandle,self.endEffector=mc.ikHandle(sol='ik2Bsolver',sj=self.ctrlJoints[0],ee=self.ctrlJoints[-1],n=uniqueNames(self.name+'Handle')) self.endEffector=mc.rename(self.endEffector,self.name+'Effector') mc.setAttr(self.ikHandle+'.snapEnable',False) mc.hide(self.ikHandle) mc.setAttr(self.ikHandle+'.ikBlend',0) for j in self.originalRotations: if isIterable(self.originalRotations[j]): mc.setAttr(j,*self.originalRotations[j]) else: mc.setAttr(j,self.originalRotations[j]) # look for twist joints if self.twist: skipAxis=removeAll(self.orientAxis,['x','y','z']) twistJoints=removeAll([self.joints[-2],self.joints[-1]],hierarchyBetween(self.joints[-2],self.joints[-1],type='joint')) for i in range(0,len(twistJoints)): tj=twistJoints[i] oc=mc.orientConstraint(self.ctrlJoints[-1],tj,sk=skipAxis,mo=True) if i>0: oc=mc.orientConstraint(self.ctrlJoints[-2],tj,sk=skipAxis,mo=True) wal=mc.orientConstraint(oc,q=True,wal=True) distToBend=distanceBetween(self.ctrlJoints[-2],tj) distToEnd=distanceBetween(self.ctrlJoints[-1],tj) mc.setAttr(oc+'.'+wal[-1],distToEnd/(distToBend+distToEnd)) mc.setAttr(oc+'.'+wal[-2],distToBend/(distToBend+distToEnd)) # make stretchy db=mc.createNode('distanceBetween') mc.connectAttr(self.ctrlJoints[0]+'.t',db+'.p1') pmm1=mc.createNode('pointMatrixMult') pmm2=mc.createNode('pointMatrixMult') mc.connectAttr(self.ikHandle+'.t',pmm1+'.ip') mc.connectAttr(self.ikHandle+'.pm[0]',pmm1+'.im') mc.connectAttr(pmm1+'.o',pmm2+'.ip') mc.connectAttr(self.ctrlJoints[0]+'.pim[0]',pmm2+'.im') mc.connectAttr(pmm2+'.o',db+'.p2') mdl=mc.createNode('multDoubleLinear') mc.connectAttr(db+'.d',mdl+'.i1') mc.setAttr(mdl+'.i2',1.0/mc.getAttr(db+'.d')) cn=mc.createNode('clamp') for i in range(0,3): c=['r','g','b'][i] a=['x','y','z'][i] mc.connectAttr(mdl+'.o',cn+'.ip'+c) mc.setAttr(cn+'.mn'+c,1) mc.connectAttr(mdl+'.o',cn+'.mx'+c) mc.connectAttr(cn+'.op'+c,self.ctrlJoints[0]+'.s'+a) for cmo in cMuscleObjects: mdlcm=mc.createNode('multDoubleLinear') mc.setAttr(mdlcm+'.i1',mc.getAttr(cmo+'.length')) mc.connectAttr(cn+'.op'+['r','g','b'][['x','y','z'].index(self.orientAxis)],mdlcm+'.i2') mc.connectAttr(mdlcm+'.o',cmo+'.length') # create control objects or set control object pivots poleOffset=distanceBetween(self.ctrlJoints[1],self.ctrlJoints[0])*2 for i in range(0,len(self.controlObjects)-1): if mc.objExists(self.controlObjects[i]): mc.xform(self.controlObjects[i],ws=True,piv=mc.xform(self.ctrlJoints[-1],q=True,ws=True,rp=True)) else: if 'r' not in self.handleOptions[i] and 'radius' not in self.handleOptions[i]: self.handleOptions[i]['r']=distanceBetween(self.ctrlJoints[-1],self.ctrlJoints[0])/4 if 'name' not in self.handleOptions[i] and 'n' not in self.handleOptions[i]: self.handleOptions[i]['n']=self.joints[i]+'_ctrl' if 'x' not in self.handleOptions[i] and 'xform' not in self.handleOptions[i]: self.handleOptions[i]['xform']=self.joints[i] if 'aim' not in self.handleOptions[i] and 'a' not in self.handleOptions[i]: self.handleOptions[i]['aim']=self.aimVector self.handleOptions[i]['parent']=self.group self.handleOptions[-i]['pointTo']=self.joints[i] self.handleOptions[i]['aimAt']=self.joints[i] self.handles.append(Handle(**self.handleOptions[i])) self.controlObjects[i]=(self.handles[-1].transforms[-1]) if not mc.objExists(self.controlObjects[-1]): if 'name' not in self.handleOptions[-1] and 'n' not in self.handleOptions[-1]: self.handleOptions[-1]['n']=self.joints[1]+'_aimCtrl' if 'x' not in self.handleOptions[-1] and 'xform' not in self.handleOptions[-1]: self.handleOptions[-1]['x']=self.ctrlJoints[1] if 'aim' not in self.handleOptions[i] and 'a' not in self.handleOptions[i]: self.handleOptions[i]['aim']=self.poleVector self.handleOptions[-1]['parent']=self.group self.handleOptions[-1]['pointTo']=self.joints[1] self.handleOptions[-1]['aimAt']=self.joints[1] self.handles.append(Handle(**self.handleOptions[-1])) self.controlObjects[-1]=(self.handles[-1].transforms[-1]) mc.move\ ( poleOffset*(self.poleVector[0]), poleOffset*(self.poleVector[1]), poleOffset*(self.poleVector[2]), self.controlObjects[-1], r=True,os=True,wd=True ) # add and set control attributes mc.setAttr(self.controlObjects[-1]+'.v',k=False) for attr in ['.sx','.sy','.sz']: mc.setAttr(self.controlObjects[-1]+attr,l=True,k=False,cb=False) mc.setAttr(self.ikHandle+attr,l=True,k=False,cb=False) for attr in ['.rx','.ry','.rz']: mc.setAttr(self.controlObjects[-1]+attr,k=False,cb=False) for attr in ['.tx','.ty','.tz']: mc.setAttr(self.group+attr,l=True,k=False,cb=False) mc.setAttr(self.controlObjects[0]+attr,l=True,k=False,cb=False) mc.setAttr(self.ikHandle+'.v',k=False,cb=False) for attr in ['.tx','.ty','.tz']: mc.setAttr(self.controlObjects[1]+attr,l=True,k=False,cb=False) if not mc.objExists(self.controlObjects[-2]+'.twist'): mc.addAttr(self.controlObjects[-2],at='doubleAngle',ln='twist',k=True) if not mc.objExists(self.controlObjects[-2]+'.sway') and self.sway: mc.addAttr(self.controlObjects[-2],at='doubleAngle',ln='sway',k=1) if not mc.objExists(self.controlObjects[-2]+'.stretch'): mc.addAttr(self.controlObjects[-2],at='double',ln='stretch',k=1,dv=self.stretch,min=0) if not mc.objExists(self.controlObjects[-2]+'.squash'): mc.addAttr(self.controlObjects[-2],at='double',ln='squash',k=1,dv=self.squash,min=0,max=99) if not mc.objExists(self.controlObjects[-2]+'.ikSwitch'): mc.addAttr(self.controlObjects[-2],at='enum',ln='ikSwitch',en='ik:fk',k=True,dv=1)# if self.switch=='fk' else 0 #sway control if self.sway: adl=mc.createNode('addDoubleLinear') mc.connectAttr(self.ctrlJoints[1]+'.r'+self.poleAxis,adl+'.i1') mc.connectAttr(self.controlObjects[-2]+'.sway',adl+'.i2') childList=removeAll\ ( iterable(mc.listRelatives(self.joints[2],c=True,ad=True)), iterable(mc.listRelatives(self.joints[1],c=True,ad=True)) )+[self.joints[2],self.joints[1]] for c in childList: if mc.nodeType(c)=='transform' or mc.nodeType(c)=='joint': pc=mc.parentConstraint(c,q=True) nc=listNodeConnections(self.ctrlJoints[1],pc,s=True,d=True) for conn in nc: if conn[0]==self.ctrlJoints[1]+'.rotate': mc.disconnectAttr(conn[0],conn[1]) for a in removeAll(self.poleAxis,['x','y','z']): mc.connectAttr(conn[0]+a.upper(),conn[1]+a.upper(),f=True) mc.connectAttr(adl+'.o',conn[1]+self.poleAxis.upper(),f=True) # ik/fk switch for i in range(0,3): c=['r','g','b'][i] a=['x','y','z'][i] adl=mc.createNode('addDoubleLinear') mdl1=mc.createNode('multDoubleLinear') mc.setAttr(mdl1+'.i2',.01) mdl2=mc.createNode('multDoubleLinear') mc.setAttr(mdl2+'.i2',.01) revNode=mc.createNode('reverse') mc.setAttr(adl+'.i1',1) mc.connectAttr( mdl1+'.o',adl+'.i2') mc.connectAttr(self.controlObjects[-2]+'.stretch',mdl1+'.i1') mc.connectAttr( mdl2+'.o',revNode+'.ix') mc.connectAttr(self.controlObjects[-2]+'.squash',mdl2+'.i1') mc.connectAttr(adl+'.o',cn+'.mx'+c,f=True) mc.connectAttr(revNode+'.ox',cn+'.mn'+c,f=True) if not mc.objExists(self.controlObjects[-2]+'.zenPreviousIKState'): if self.switch=='fk': mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKState',k=0,dv=1) else: mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKState',k=0,dv=0) if not mc.objExists(self.controlObjects[-2]+'.zenPreviousIKParent'): if self.switch=='fk': mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKParent',k=0,dv=1) else: mc.addAttr(self.controlObjects[-2],at='long',ln='zenPreviousIKParent',k=0,dv=0) for i in range(0,2): for c in mc.listRelatives(self.controlObjects[i],s=True): mc.connectAttr(self.controlObjects[-2]+'.ikSwitch',c+'.v') mc.connectAttr(self.controlObjects[-2]+'.twist',self.ikHandle+'.twist') rev=mc.createNode('reverse') mc.connectAttr(self.controlObjects[-2]+'.ikSwitch',rev+'.ix') mc.connectAttr(rev+'.ox',self.ikHandle+'.ikBlend') for c in mc.listRelatives(self.controlObjects[-1],s=True): mc.connectAttr(rev+'.ox',c+'.v') # parent spaces for i in [0,1,2]: if(mc.objExists(self.jointParent)and i in [0,2]): ParentSpace(self.controlObjects[i],self.jointParent) else: ParentSpace(self.controlObjects[i],self.controlObjects[i-1]) ParentSpace(self.controlObjects[-1],self.controlObjects[-2]) if mc.objExists(self.jointParent): ParentSpace(self.controlObjects[-1],self.jointParent).setParent(self.jointParent) ParentSpace(self.controlObjects[-2],self.jointParent).setParent(self.jointParent) else: ParentSpace(self.controlObjects[-1],self.controlObjects[0]) if self.switch=='fk': ParentSpace(self.controlObjects[2],self.controlObjects[1]) for co in self.controlObjects[2:]: freeze(co,t=True) mc.aimConstraint\ ( self.ctrlJoints[1],self.controlObjects[-1], aim=(self.aimVector[0],self.aimVector[1],self.aimVector[2]), wuo=self.ctrlJoints[1], wut='objectrotation', mo=True ) if mc.objExists(self.jointParent): mc.setAttr(self.controlObjects[0]+'.parentTo',l=True,k=False,cb=False) mc.setAttr(self.controlObjects[1]+'.parentTo',l=True,k=False,cb=False) #constraints orientConstraints=['','',''] for i in [2,1,0]: orientConstraints[i]=mc.orientConstraint(self.controlObjects[i],self.ctrlJoints[i],mo=True)[0] mc.setAttr(self.controlObjects[i]+'.v',k=False) for attr in ['.sx','.sy','.sz']: mc.setAttr(self.controlObjects[i]+attr,l=True,k=False,cb=False) if i==1: if not self.sway: mc.setAttr(self.controlObjects[i]+'.r'+self.poleAxis,l=True,k=False,cb=False) mc.setAttr(self.controlObjects[i]+'.r'+self.orientAxis,l=True,k=False,cb=False) self.poleVectorConstraint=mc.poleVectorConstraint(self.controlObjects[-1],self.ikHandle)[0] for oc in orientConstraints[:-1]: octl=mc.orientConstraint(oc,q=True,tl=True) ocwal=mc.orientConstraint(oc,q=True,wal=True) weightAlias=ocwal[octl.index(self.controlObjects[orientConstraints.index(oc)])] mc.connectAttr(self.controlObjects[-2]+'.ikSwitch',oc+'.'+weightAlias) mc.parent(self.ikHandle,self.controlObjects[2],r=False) if self.switch=='ik': mc.setAttr(self.controlObjects[-2]+'.ikSwitch',0) # link for asset detection if 'zenIkFkLimbCtrls' not in mc.listAttr(self.group): mc.addAttr(self.group,ln='zenIkFkLimbCtrls',at='message',m=True) if 'zenIkFkLimbCtrlJoints' not in mc.listAttr(self.group): mc.addAttr(self.group,ln='zenIkFkLimbCtrlJoints',at='message',m=True) for co in self.controlObjects: if 'zenCtrl' not in mc.listAttr(co): mc.addAttr(co,ln='zenCtrl',at='message') mc.connectAttr(co+'.zenCtrl',self.group+'.zenIkFkLimbCtrls['+str(firstOpenPlug(self.group+'.zenIkFkLimbCtrls'))+']') for cj in self.ctrlJoints: if 'zenCtrl' not in mc.listAttr(cj): mc.addAttr(cj,ln='zenCtrl',at='message') mc.connectAttr(cj+'.zenCtrl',self.group+'.zenIkFkLimbCtrlJoints['+str(firstOpenPlug(self.group+'.zenIkFkLimbCtrlJoints'))+']') for bp in self.bindPoses: for co in self.controlObjects: mc.dagPose(co,a=True,n=bp) self[:]=[self.group]+self.controlObjects mc.cycleCheck(e=True) mc.select(self[-2])
def addAttributes(self,**keywords): #organize: sortedKeywords=sortBy\ ( keywords, [ 'position', 'scale', 'sweep', 'spin', 'radius', 'normal' ] ) for k in sortedKeywords: attrVal=eval('self.'+k) if isIterable(attrVal): attrType='double3' else: attrType='double' if k in self.attributeTypes: attrType=self.attributeTypes[k] else: self.attributeTypes[k]=attrType if not k in mc.listAttr(self.shapes[-1]): if k in self.attributeShortNames: mc.addAttr(self.shapes[-1],ln=k,sn=self.attributeShortNames[k],at=attrType) else: mc.addAttr(self.shapes[-1],ln=k,at=attrType) if isIterable(attrVal): subAttrType=attrType[:-1] if k in self.attributeShortNames: mc.addAttr(self.shapes[-1],ln=k+'X',sn=self.attributeShortNames[k]+'x',at=subAttrType,p=k) mc.addAttr(self.shapes[-1],ln=k+'Y',sn=self.attributeShortNames[k]+'y',at=subAttrType,p=k) mc.addAttr(self.shapes[-1],ln=k+'Z',sn=self.attributeShortNames[k]+'z',at=subAttrType,p=k) else: mc.addAttr(self.shapes[-1],ln=k+'X',at=subAttrType,p=k) mc.addAttr(self.shapes[-1],ln=k+'Y',at=subAttrType,p=k) mc.addAttr(self.shapes[-1],ln=k+'Z',at=subAttrType,p=k) mc.setAttr(self.shapes[-1]+'.'+k+'X',k=False,cb=True) mc.setAttr(self.shapes[-1]+'.'+k+'Y',k=False,cb=True) mc.setAttr(self.shapes[-1]+'.'+k+'Z',k=False,cb=True) if k in self.attributeLimits: mc.addAttr(self.shapes[-1]+'.'+k+'X',e=True,min=self.attributeLimits[k][0][0],max=self.attributeLimits[k][-1][0]) mc.addAttr(self.shapes[-1]+'.'+k+'Y',e=True,min=self.attributeLimits[k][0][1],max=self.attributeLimits[k][-1][1]) mc.addAttr(self.shapes[-1]+'.'+k+'Z',e=True,min=self.attributeLimits[k][0][2],max=self.attributeLimits[k][-1][2]) else: if k in self.attributeLimits: mc.addAttr(self.shapes[-1]+'.'+k,e=True,min=self.attributeLimits[k][0],max=self.attributeLimits[k][-1]) if isIterable(attrVal): mc.setAttr(self.shapes[-1]+'.'+k,*attrVal,**{'cb':True,'k':False}) else: mc.setAttr(self.shapes[-1]+'.'+k,attrVal,k=False,cb=True) if isIterable(keywords[k]): connectTo=keywords[k] else: connectTo=[keywords[k]] for c in connectTo: if isinstance(connectTo,dict): for cc in connectTo: if not mc.isConnected(self.shapes[-1]+'.'+k+cc,connectTo[cc]): mc.connectAttr(self.shapes[-1]+'.'+k+cc,connectTo[cc],f=True) else: if not mc.isConnected(self.shapes[-1]+'.'+k,c): mc.connectAttr(self.shapes[-1]+'.'+k,c,f=True)
def __init__(self,*args,**keywords): #defaults self.parent='' self.transforms=[] self.name='' self.pointTo='' self.aimAt='' self.aim=[0,1,0] self.up=[0,0,1] self.pivot=[] self.type='locator' self.shape='' self.shapes=[] self.radius=1 self.sweep=90 self.position=[0,0,0] self.scale=[1,1,1] self.xform='' self.spin=0 self.xformMatrix=[] self.freeze=False self.softParent='' # attributes self.parentSpaces=[] self.shortNames=\ { 'p':'parent', 'f':'freeze', 'n':'name', 'tan':'tangent', 'pv':'pivot', 'piv':'pivot', 'tr':'transform', 'pct':'parentCtrl', 'pctrl':'parentCtrl', 'ctrl':'control', 'rad':'radius', 'r':'radius', 'sw':'sweep', 'pos':'position', 't':'type', 'x':'xform', 'aa':'aimAt', 'sp':'softParent' } self.attributeTypes=\ { 'normal':'float3', 'up':'double3', 'aim':'double3', 'sweep':'double', 'spin':'double' } self.attributeLimits=\ { 'normal':[[-1,-1,-1],[1,1,1]], 'up':[[-1,-1,-1],[1,1,1]], 'aim':[[-1,-1,-1],[1,1,1]], 'sweep':[0,180], 'spin':[-225,135], 'radius':[0,10000000] } self.attributeShortNames=\ { 'position':'pos', 'radius':'rad', 'spin':'sp', 'sweep':'sw', 'normal':'nr' } 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]') if len(args)==0 and not mc.objExists(self.xform): args=mc.ls(sl=True) sel=[] for a in args: if isIterable(a): sel.extend(a) else: sel.append(a) for s in sel: if mc.ls(s)==mc.ls(s,type='transform'): self.transforms.append(mc.ls(s)[0]) elif mc.ls(s)==mc.ls(s,type='shape'): self.transforms.append(mc.ls(s)[0]) # parse options if self.name=='': self.name='Handle#' if not isIterable(self.position): if isinstance(self.position,basestring) and mc.objExists(self.position): if len(iterable(self.position.split('.')))>1: try: self.position=mc.pointPosition(self.position) except: self.position=mc.pointPosition(self.position+'.rp') else: self.position=mc.pointPosition(self.position+'.rp') elif len(self.position)<3: self.position=[0.0,0.0,0.0] if self.transforms==[]: if 'freeze' not in keywords and 'f' not in keywords: self.freeze=True if mc.objExists(self.xform): self.transforms.append(mc.createNode('transform',n=self.name,p=self.xform)) mc.setAttr(self.transforms[-1]+'.r',0,0,0) else: self.transforms.append(mc.createNode('transform',n=self.name)) if mc.objExists(self.parent): mc.parent(self.transforms[-1],self.parent) else: mc.parent(self.transforms[-1],w=True) """if mc.objExists(self.xform): xfm=mc.xform(self.xform,q=True,ws=True,a=True,m=True) wsro=mc.xform(self.xform,q=True,ws=True,ro=True) wst=mc.xform(self.xform,q=True,ws=True,t=True) wsrp=mc.xform(self.xform,q=True,ws=True,rp=True) wsra=mc.xform(self.xform,q=True,ws=True,ra=True) wssp=mc.xform(self.xform,q=True,ws=True,sp=True) print self.transforms[-1] print xfm mc.xform(self.transforms[-1],ws=True,a=True,m=xfm) mc.xform(self.transforms[-1],ws=True,ro=wsro) mc.xform(self.transforms[-1],ws=True,t=wst) mc.xform(self.transforms[-1],ws=True,rp=wsrp) mc.xform(self.transforms[-1],ws=True,ra=wsra) mc.xform(self.transforms[-1],ws=True,sp=wssp) print mc.xform(self.transforms[-1],q=True,a=True,ws=True,m=True)""" elif mc.objExists(self.parent): for t in self.transforms: mc.parent(t,self.parent) if mc.objExists(self.softParent): for t in self.transforms: self.parentSpaces.append(ParentSpace(t,self.softParent)) if self.freeze: freeze(self.transforms[-1],t=True) if mc.objExists(self.pointTo): self.aimCurve=mc.createNode('nurbsCurve',p=self.transforms[0]) if len(self.shapes)==0: exec('self.mk'+self.type[0].upper()+self.type[1:]+'()') if mc.objExists(self.pointTo): self.mkAim() for t in self.transforms: if not 'zenHandleShape' in mc.listAttr(t): mc.addAttr(t,ln='zenHandleShape',m=True,at='message') for s in self.shapes: if not 'zenHandle' in mc.listAttr(s): mc.addAttr(s,ln='zenHandle',at='message') for t in self.transforms: for s in self.shapes: mc.connectAttr\ ( s+'.zenHandle', t+'.zenHandleShape['+str(firstOpenPlug(t+'.zenHandleShape'))+']' ) if len(self.transforms)>1: for t in self.transforms[1:]: pass self[:]=self.shapes
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 deferExec(*args,**keywords): #defaults melCommand=False repeatable=True showErrors=True shortNames={ 'mel':'melCommand', 're':'repeatable', 'se':'showErrors' } if len(args)==0: return for k in keywords: if k in locals(): exec(k+'=keywords[k]') elif k in shortNames: exec(shortNames[k]+'=keywords[k]') zdc=MelGlobalVar('zenDelayedCommands') dcStr=zdc.get() if isinstance(dcStr,basestring): dc=dcStr.split(';') else: dcStr='' dc=[] dcsjVar=MelGlobalVar('zenDelayedCommandsSJ') dcsj=dcsjVar.get() if type(dcsj).__name__=='NoneType': dcsj='' for a in args: if not repeatable: dc.remove(a) if isinstance(a,basestring): if melCommand: dc.append(a) else: lines=a.split('\n') if len(lines)==1: dc.append('python('+melEncode(a)+')') else: pyCmd='python(\n' for l in lines: pyCmd+=melEncode(l+'\n')+'+\n' pyCmd=pyCmd[:-2]+')' dc.append(pyCmd) sjExists=False if isIterable(dc) and len(dc)>0 and isinstance(dcsj,(int,long,float)) and dcsj!=0 and mel.eval('scriptJob -ex '+str(dcsj)): sjExists=True dc=removeAll([''],dc) zdc.set(';'.join(dc)) if not(sjExists): cmd=( 'scriptJob \n'+ ' -ro true\n'+ ' -e "idle" \n'+ ' (\n'+ ' '+melEncode('string $zenDeferExec_errCmds[]={};\n')+'+\n'+ ' '+melEncode('for($c in (stringArrayRemoveDuplicates(stringToStringArray($zenDelayedCommands,\";\"))))\n')+'+\n'+ ' '+melEncode('{\n')+'+\n'+ ' '+melEncode(' if(catch(`eval($c)`)) $zenDeferExec_errCmds[size($zenDeferExec_errCmds)]=$c;\n')+'+\n'+ ' '+melEncode('}\n')+'+\n'+ ' '+melEncode('for($c in $zenDeferExec_errCmds) warning("errors encountered: \\n"+$c+"\\n");\n')+'+\n'+ ' '+melEncode('$zenDelayedCommands="";\n')+'+\n'+ ' '+melEncode('$zenDelayedCommandsSJ=0;\n')+'\n'+ ' )' ) dcsjVar.set(mel.eval(cmd))
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 __init__(self,*args,**keywords): # default options self.name='limb' self.stretch=20 self.squash=0 self.twist=True # performs auto detect self.sway=True self.switch='ik' # initial ik/fk switch state self.handleOptions=[{'type':'doubleEllipse','spin':-180},{'type':'doubleEllipse','spin':-90},{'type':'doubleEllipse'},{'type':'locator'}] self.tol=1.0 # angle tolerance for preferred angles self.parent='' self.shortNames=\ { 'n':'name', 'p':'parent', 'sp':'softParent', 'co':'controlObjects', 'ho':'handleOptions' } # attributes self.controlObjects=['','','',''] self.bindPoses=[] self.joints=[] self.group='' self.orientAxis='' self.bendAxis='' self.poleAxis='' self.ctrlJoints=[] self.handles=[] self.endEffector='' self.ikHandle='' self.jointParent='' self.jointParent='' self.originalRotations={} self.bendDirection=0 self.poleVector=[] self.poleVectorWorld=[] self.upVector=[] self.aimVector=[] self.parentSpaces=[] for k in keywords: if k in self.__dict__: exec('self.'+k+'=keywords[k]') elif k in self.shortNames: exec('self.'+self.shortNames[k]+'=keywords[k]') uniqueNames(re=True) if len(args)==0: args=mc.ls(sl=True) sel=[] for a in args: sel.extend(iterable(a)) sel=hierarchyOrder(sel) # parse options defualtHandleOptions=[{'type':'doubleEllipse','spin':-180},{'type':'doubleEllipse','spin':-90},{'type':'doubleEllipse'},{'type':'locator'}] i=len(self.handleOptions) while len(self.handleOptions)<4: self.handleOption.append(defualtHandleOptions[i]) i+=1 if isinstance(self.handleOptions,dict): self.handleOptions=[self.handleOptions,self.handleOptions,self.handleOptions] elif isIterable(self.handleOptions): if len(self.handleOptions)==0: self.handleOptions.append({}) while len(self.handleOptions)<3: self.handleOptions.append(self.handleOptions[-1]) else: self.handleOptions=[{},{},{}] self.controlObjects=iterable(self.controlObjects) self.orientAxis=self.orientAxis.lower() self.baseTwist='' self.hierarchy=[] if len(sel)>2: for j in sel[:-1]: if len(hierarchyBetween(j,sel[-1]))>len(self.hierarchy): self.hierarchy=hierarchyBetween(j,sel[-1]) closest=9e999 for s in removeAll([self.hierarchy[0],self.hierarchy[-1]],sel): if\ ( len(iterable(mc.listRelatives(self.hierarchy[0],p=True)))==0 or s in mc.listRelatives(mc.listRelatives(self.hierarchy[0],p=True)[0],c=True,type='joint') ): dist=distanceBetween(s,self.hierarchy[0]) if dist<closest: closest=dist self.baseTwist=s else: self.hierarchy=hierarchyBetween(sel[0],sel[-1]) self.bindPoses=iterable(getBindPoses(self.hierarchy)) self.joints=['','',''] if len(self.hierarchy)<3: raise Exception('There are no joints between your start and end joint. No IK created.') self.joints[0]=self.hierarchy[0] self.joints[-1]=self.hierarchy[-1] # find the orientation axis self.orientAxis='x' axisLen={'x':0,'y':0,'z':0} for j in self.hierarchy[1:]: for a in ['x','y','z']: axisLen[a]+=abs(mc.getAttr(j+'.t'+a)) if axisLen[a]>axisLen[self.orientAxis]: self.orientAxis=a # find bend joint and pole vector self.originalRotations={} for j in self.hierarchy[1:-1]: # check to see if any have a non-zero preferred angle for a in removeAll(self.orientAxis,['x','y','z']): if abs(mc.getAttr(j+'.pa'+a))>=self.tol: self.originalRotations[j+'.r'+a]=mc.getAttr(j+'.r'+a) mc.setAttr(j+'.r'+a,mc.getAttr(j+'.pa'+a)) greatestAngle=0 for j in self.hierarchy[1:-1]: jPos=mc.xform(j,q=True,ws=True,rp=True) prevJPos=mc.xform(self.hierarchy[self.hierarchy.index(j)-1],q=True,ws=True,rp=True) nextJPos=mc.xform(self.hierarchy[self.hierarchy.index(j)+1],q=True,ws=True,rp=True) vAngle=mc.angleBetween(v1=normalize(jPos[0]-prevJPos[0],jPos[1]-prevJPos[1],jPos[2]-prevJPos[2]),v2=normalize(nextJPos[0]-jPos[0],nextJPos[1]-jPos[1],jPos[2]-jPos[2]))[-1] if abs(vAngle)>greatestAngle: greatestAngle=abs(vAngle) self.joints[1]=j mp=midPoint\ ( self.hierarchy[0],self.hierarchy[-1], bias=\ ( distanceBetween(self.hierarchy[0],self.joints[1])/ (distanceBetween(self.hierarchy[0],self.joints[1])+distanceBetween(self.joints[1],self.hierarchy[-1])) ) ) bendPoint=mc.xform(self.joints[1],q=True,ws=True,rp=True) self.poleVectorWorld=normalize\ ( bendPoint[0]-mp[0], bendPoint[1]-mp[1], bendPoint[2]-mp[2] ) pmm=mc.createNode('pointMatrixMult') mc.setAttr(pmm+'.vm',True) mc.connectAttr(self.joints[1]+'.worldInverseMatrix',pmm+'.im') mc.setAttr(pmm+'.ip',*self.poleVectorWorld) self.poleVector=mc.getAttr(pmm+'.o')[0] disconnectNodes(pmm) mc.delete(pmm) greatestLength=0.0 for i in [0,1,2]: if abs(self.poleVector[i])>greatestLength and ['x','y','z'][i]!=self.orientAxis: self.poleAxis=['x','y','z'][i] greatestLength=abs(self.poleVector[i]) self.bendDirection=-abs(self.poleVector[i])/self.poleVector[i] for r in self.originalRotations: mc.setAttr(r,self.originalRotations[r]) preferredAngleWarning=False if not mc.objExists(self.joints[1]): preferredAngleWarning=True mp=midPoint(self.hierarchy[0],self.hierarchy[-1]) cd=9e999 dist=0 for j in self.hierarchy[1:-1]: dist=distanceBetween(j,mp) if dist<cd: cd=dist self.joints[1]=j self.bendAxis=removeAll(self.orientAxis,['z','y','x'])[0] if self.poleAxis=='': self.poleAxis=removeAll([self.orientAxis,self.bendAxis],['x','y','z'])[0] if self.bendAxis=='': self.bendAxis=removeAll([self.orientAxis,self.poleAxis],['x','y','z'])[0] if self.orientAxis=='': self.orientAxis=removeAll([self.bendAxis,self.poleAxis],['x','y','z'])[0] if self.poleAxis=='x': self.poleVector=[-self.bendDirection,0.0,0.0] if self.poleAxis=='y': self.poleVector=[0.0,-self.bendDirection,0.0] if self.poleAxis=='z': self.poleVector=[0.0,0.0,-self.bendDirection] if self.bendAxis=='x': self.upVector=[-self.bendDirection,0.0,0.0] if self.bendAxis=='y': self.upVector=[0.0,-self.bendDirection,0.0] if self.bendAxis=='z': self.upVector=[0.0,0.0,-self.bendDirection] if self.orientAxis=='x': self.aimVector=[self.bendDirection,0.0,0.0] if self.orientAxis=='y': self.aimVector=[0.0,self.bendDirection,0.0] if self.orientAxis=='z': self.aimVector=[0.0,0.0,self.bendDirection] if mc.objExists(self.baseTwist): conn=False for a in ['.r','.rx','.ry','.rz']: if mc.connectionInfo(self.baseTwist+a,id=True): conn=True if not conn: mc.orientConstraint(self.joints[0],self.baseTwist,sk=self.orientAxis) # load ik2Bsolver - ikRPSolver does not work well with this setup mel.eval('ik2Bsolver') self.create() if preferredAngleWarning: raise Warning('Warning: Joints are co-linear and no preferred angles were set. Results may be unpredictable.')
def midPoint(*args, **keywords): # weighted midPoint world = False local = False bias = 0.5 # 0.0==point1, 1.0==point2 shortNames = {"w": "world", "l": "local", "b": "bias"} for k in keywords: if k in locals(): exec(k + "=keywords[k]") if k in shortNames: exec(shortNames[k] + "=keywords[k]") if not (world or local): world = True if len(args) == 0: args = mc.ls(sl=True) if len(args) == 0: return p = [] for a in args: if isIterable(a) and len(a) >= 3 and isinstance(a[0], (float, long, int)) and len(a) >= 3: p.append(a) elif isinstance(a, basestring) and mc.objExists(a): if len(a.split(".")) > 1: try: p.append(mc.pointPosition(a, w=world, l=local)) except: if mc.nodeType(mc.ls(a, o=True)) == "mesh": for v in iterable(mc.ls(mc.polyListComponentConversion(a, tv=True), fl=True)): p.append(mc.pointPosition(v, w=world, l=local)) else: try: p.append(mc.pointPosition(a + ".rp", w=world, l=local)) except: err = True if len(p) < 1: return if len(p) == 1: return p[0] mp = [0.0, 0.0, 0.0] if len(p) == 2: # use bias mp = ( (float(p[0][0]) * (1 - bias) + float(p[-1][0]) * bias), (float(p[0][1]) * (1 - bias) + float(p[-1][1]) * bias), (float(p[0][2]) * (1 - bias) + float(p[-1][2]) * bias), ) else: # disregard bias for pp in p: mp = ( mp[0] + (float(pp[0]) * (1.0 / float(len(p)))), mp[1] + (float(pp[1]) * (1.0 / float(len(p)))), mp[2] + (float(pp[2]) * (1.0 / float(len(p)))), ) return mp
def __init__(self,*args,**keywords): #check to make sure unique names are used in scene uniqueNames(iterable(mc.ls(type='dagNode')),re=True) #default options self.number=1 #if there are no transforms, create this many rivets self.distribute='' self.parents=['',''] self.rebuild=False self.taper='none' # none, normal, distance self.scale='none' # none, uniform, or relative self.scaleDirection=['length','width'] # length, width self.createAimCurve=False self.aimCurve='' self.handles=[] self.handleShapes=[] self.autoFlexGroups=[] self.mo=True # maintain offset self.ctrls=[] #by default control attributes are placed on given transforms self.keepPivot=True self.snapToSurface=False self.realign=False self.rivets=[] self.ClosestPoints=[] self.aimGroups=[] self.softParents=[] self.ArcCtrl=[] self.arcWeight=.5 self.closestPoint='' # geometry, pivot self.organize=True self.constraint=False # use a parent constraint self.parent=False # create a transform and parent objects to it self.spaceTr='' self.surfaceAttr='' self.bindPoses=[] self.parentSpaces=[] self.hasGeometry=True self.skipRotate=[] self.skipTranslate=[] self.skipScale=[] self.skipScaleObjects=[] self.skipRotateObjects=[] self.skipTranslateObjects=[] self.minScaleWidth=0 self.maxScaleWidth=1 self.minScaleLength=0 self.maxScaleLength=1 self.surfaceMatrix='' self.surfaceInverseMatrix='' self.worldMatrix='' self.trs=[] self.uSpans=-1 self.vSpans=-1 self.skins=[] self.shortNames=\ { 'sd':'scaleDirection', 'p':'parents', 'sp':'softParents' } sel=[] if len(args)==0: sel=mc.ls(sl=True) for a in args: sel.extend(iterable(a)) self.bindPoses=iterable(getBindPoses(sel)) if len(self.bindPoses)>0: goToDagPose(self.bindPoses[0]) self.edges=PolyEdgeList(sel,f=True) self.trs=removeDuplicates(mc.ls(self.edges.etcObj,tr=True)) if len(self.edges)==0: #look for a surface or surface attribute reversedObjList=getReversed(self.edges.etcObj) for obj in reversedObjList: if len(obj.split('.'))>1 and mc.getAttr(obj,type=True)=='nurbsSurface': self.surfaceAttr=obj obj=mc.ls(self.surfaceAttr,o=True)[0] if mc.nodeType(obj)=='nurbsSurface': self.uSpans=mc.getAttr(obj+'.spansU') self.vSpans=mc.getAttr(obj+'.spansV') self.spaceTr=mc.listRelatives(obj,p=True)[0] break elif mc.nodeType(obj)=='nurbsSurface': self.surfaceAttr=obj+'.worldSpace[0]' self.spaceTr=mc.listRelatives(obj,p=True)[0] self.uSpans=mc.getAttr(obj+'.spansU') self.vSpans=mc.getAttr(obj+'.spansV') self.trs.remove(obj) break else: children=mc.listRelatives(obj,c=True,s=True,ni=True,type='nurbsSurface') if isIterable(children) and len(children)>0: self.spaceTr=mc.ls(obj)[0] self.surfaceAttr=children[0]+'.worldSpace[0]' self.uSpans=mc.getAttr(children[0]+'.spansU') self.vSpans=mc.getAttr(children[0]+'.spansV') self.trs.remove(obj) break else: self.spaceTr=self.edges.getTr() for k in keywords: if k in self.__dict__: exec('self.'+k+'=keywords[k]') elif k in self.shortNames: exec('self.'+self.shortNames[k]+'=keywords[k]') if len(iterable(self.parents))==1: self.parents=[iterable(self.parents)[0],iterable(self.parents)[0]] if len(iterable(self.softParents))==1: self.softParents=[iterable(self.softParents)[0],iterable(self.softParents)[0]] if len(self.ctrls)==0: self.ctrls=self.trs while len(self.ctrls)<len(self.trs): self.ctrls.append(self.ctrls[-1]) if len(self.skipRotate)>0: for i in self.skipRotate: self.skipRotateObjects.append(self.trs[self.skipRotate[i]]) if len(self.skipTranslate)>0: for i in self.skipTranslate: self.skipTranslateObjects.append(self.trs[self.skipTranslate[i]]) if len(self.skipScale)>0: for i in self.skipScale: self.skipScaleObjects.append(self.trs[self.skipScale[i]]) if len(self.trs)>0: for t in self.trs: shCount=len\ ( removeDuplicates(mc.listRelatives(t,c=True,type='nurbsSurface'))+ removeDuplicates(mc.listRelatives(t,c=True,type='nurbsCurve'))+ removeDuplicates(mc.listRelatives(t,c=True,type='mesh')) ) if shCount==0: self.hasGeometry=False self.closestPoint='pivot' break if self.closestPoint=='' and self.hasGeometry: # default to pivot if using snap to surface, otherwise defualts to geometry if self.snapToSurface: self.closestPoint='pivot' else: self.closestPoint='geometry' if len(self.trs)!=0: self.number=len(self.trs) if len(self.ctrls)<len(self.trs): self.ctrls=self.trs if not self.parent and not self.constraint: self.parent=True if self.createAimCurve: self.parent=True #self.constraint=False #find the root joint if present try: joints=removeDuplicates(mc.listConnections(iterable(mc.ls(iterable(mc.listHistory(self.surfaceAttr)))),type='joint')) if len(joints)>0: self.spaceTr=hierarchyOrder(joints)[0] except: pass self.create()